簡體   English   中英

來自嵌套對象數組的 MongoDB 聚合

[英]MongoDB aggregation from nested array of objects

我正在做一個學校項目,我需要在contentId上加入主題文檔和內容文檔。 但是,我不能使用貓鼬,因為我正在使用學校提供的堆棧。 這是一個解釋我的問題的例子:

示例主題文檔:

{
  _id: ObjectId('000000000000000000000100')
  name: "My subject"
  description: "Lorem ipsum..."
  language: "en",
  topics: [
    {
      id: ObjectId('000000000000000000000200'),
      name: "The first topic",
      description: "Lorem ipsum...",
      content: [
        {
          contentId: ObjectId('000000000000000000000300'),
          visibility: true,
        },
        {
          url: "stackoverflow.com",
          title: "Stack Overflow",
          type: "website"
        }
      ]
    }
  ]
}

示例內容文檔:

{
  _id: ObjectId('000000000000000000000300'),
  title: "Example content",
  description: "Example course in MongoDB",
  url: "http://example.com/believe/apparatus.php?birthday=bed&boot=bead"
  type: "other"
}

我需要聚合的結果如下所示:

{
  _id: ObjectId('000000000000000000000100')
  name: "My subject"
  description: "Lorem ipsum..."
  language: "en",
  topics: [
    {
      id: ObjectId('000000000000000000000200'),
      name: "The first topic",
      description: "Lorem ipsum...",
      content: [
        {
          _id: ObjectId('000000000000000000000300'),
          title: "Example content",
          description: "Example course in MongoDB",
          url: "http://example.com/believe/apparatus.php?birthday=bed&boot=bead"
          type: "other"
          visibility: true,
        },
        {
          url: "stackoverflow.com",
          title: "Stack Overflow",
          type: "website"
        }
      ]
    }
  ]
}

我嘗試了一些 $unwind 和 $lookup 組合,但沒有一個返回正確的結果。

有沒有辦法在不使用貓鼬的情況下做到這一點? 謝謝你。

詢問

  • 查找字段將是topics.content.contentId一個數組,其中包含我們要加入的所有值
  • 進行查找,匹配文檔將繼續results
  • 然后使用嵌套的$map進入內部以放置我們發現它們匹配的值。 $filter用於從結果中獲取匹配的文檔,因此我們替換了它)

*這是一種避免雙重展開並保持文檔結構不變的方法,存在替代方法,使最后一個$set更簡單,但我認為它們不會更快(如單次展開和查找然后分組)我們一點也不放松。

趣味游戲

aggregate(
[{"$set": 
   {"lookup-fields": 
     {"$reduce": 
       {"input": "$topics.content.contentId",
        "initialValue": [],
        "in": 
         {"$let": 
           {"vars": {"this": "$$value", "value": "$$this"},
            "in": {"$concatArrays": ["$$value", "$$this"]}}}}}}},
 {"$lookup": 
   {"from": "content",
    "localField": "lookup-fields",
    "foreignField": "_id",
    "as": "results"}},
 {"$set": 
   {"topics": 
     {"$map": 
       {"input": "$topics",
        "as": "lv1",
        "in": 
         {"$mergeObjects": 
           ["$$lv1",
             {"content": 
               {"$map": 
                 {"input": "$$lv1.content",
                  "as": "lv2",
                  "in": 
                   {"$cond": 
                     [{"$in": ["$$lv2.contentId", "$lookup-fields"]},
                       {"$mergeObjects": 
                         [{"$first": 
                             {"$filter": 
                               {"input": "$results",
                                "cond": {"$eq": ["$$this._id", "$$lv2.contentId"]}}}},
                          "$$lv2"]},
                      "$$lv2"]}}}}]}}}}},
 {"$unset": ["lookup-fields", "results"]}])

暫無
暫無

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

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