簡體   English   中英

從多個文檔中獲取一個數組字段並將元素合並到一個object

[英]Get an array field from multiple documents and merge elements into one object

例如,我有一個users集合。 每個用戶文檔都有posts數組,包含他們的帖子。 我想像這樣查詢這個集合:

從用戶名數組中的每個用戶Nend從索引Nstart開始到 Nend 結束的 2 個帖子: ['user1', 'user2']並返回一個合並的帖子數組,按 post.postedOn int 的升序排序。

如果這是集合:

{
  username: "user1",
  posts: [
    { id: 1, text: "123" ... },
    { id: 2, text: "456" ... },
    { id: 3, text: "789" ... },
    ...
  ]
},
{
  username: "user2",
  posts: [
    { id: 1, text: "abc" ... },
    { id: 2, text: "def" ... },
    { id: 3, text: "ghi" ... },
    ...
  ]
}
...

我想得到這個:

{
  posts: {
    { id: 1, text: "123" ... },
    { id: 2, text: "456" ... },
    { id: 1, text: "abc" ... },
    { id: 2, text: "def" ... },
  }
}

我曾多次嘗試使用aggregate 這是我的疑問之一:

db.getCollection("users").aggregate([{ $match: { username: { $in: ["admin", "admin2"] } } }, { $project: { posts: 1 } }])

我得到兩個用戶對象,每個對象都包含他們所有的帖子,而不是我以后可以操作的一個帖子數組。

我試圖達到的最終結果是:

輸入

  • 用戶: ['user1', 'user2']
  • 發帖索引: 4
  • 結束帖子索引: 8

結果

選定用戶的帖子數組。 總數為 8(每個用戶的 id 為 4-8)。

這需要使用聚合運算符$slice$push到 select 並將所需的帖子元素(按索引)分別添加到數組中。

例如, posts集合有三個文檔(我在這里省略了_id字段):

{
       "username" : "user2",
       "posts" : [
               {
                       "id" : 1,
                       "text" : "123"
               },
               {
                       "id" : 2,
                       "text" : "456"
               },
               {
                       "id" : 3,
                       "text" : "789"
               },
               {
                       "id" : 4,
                       "text" : "000"
               }
       ]
}
{
       "username" : "user1",
       "posts" : [
               {
                       "id" : 1,
                       "text" : "abc"
               },
               {
                       "id" : 2,
                       "text" : "def"
               },
               {
                       "id" : 3,
                       "text" : "ghi"
               },
               {
                       "id" : 4,
                       "text" : "zzz"
               }
       ]
}
{
        "username" : "user99",
        "posts" : [ ]
}

在 mongo shell 中:

> var users = [ "user1", "user2" ]
> var startIx = 1, noOfElements = 2

> db.posts.aggregate([ 
  { $project: { _id: 0, username: 1, posts: 1, usersMatch: { $in: [ "$username",  users ] } } },
  { $match: { usersMatch: true } },
  { $addFields: { posts: { $slice: [ "$posts", startIx, noOfElements ] } } },
  { $group: { _id: null, postsOfSelectedUsers: { $push: "$posts"} } },
  { $project: { _id: 0, selectedUsers: users, postsOfSelectedUsers: 1 } } 
])

Output:

{
        "postsOfSelectedUsers" : [
                [
                        {
                                "id" : 2,
                                "text" : "456"
                        },
                        {
                                "id" : 3,
                                "text" : "789"
                        }
                ],
                [
                        {
                                "id" : 2,
                                "text" : "def"
                        },
                        {
                                "id" : 3,
                                "text" : "ghi"
                        }
                ]
        ],
        "selectedUsers" : [
                "user1",
                "user2"
        ]
}

注意:這是一個解決方案,但可以改進或重新處理(我認為)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM