用猫鼬在Mongodb中嵌套嵌套阵列

发布于 2025-01-23 16:01:27 字数 622 浏览 0 评论 0原文

我需要过滤MongoDB中的多层嵌套阵列。模式如下,

    {
      "_id": "1234",
      "array1": [
        {
          "id": "a11",
          "array2": [
            {
              "id": "a21",
              "array3": [
                {
                  "id": "a31",
                  "status": "done"
                },
                {
                  "id": "a32",
                  "status": "pending"
                }
              ]
            }
          ]
        }
      ]
    }

所需的输出必须过滤 array3 ,条件状态=完成。哪种最佳方法可以实现同样的方法?

I need to filter a multi-level nested array in MongoDB. The schema is as follows,

    {
      "_id": "1234",
      "array1": [
        {
          "id": "a11",
          "array2": [
            {
              "id": "a21",
              "array3": [
                {
                  "id": "a31",
                  "status": "done"
                },
                {
                  "id": "a32",
                  "status": "pending"
                }
              ]
            }
          ]
        }
      ]
    }

The required output must filter array3 with condition status=done. Which is the best possible method to achieve the same?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黑白记忆 2025-01-30 16:01:27

使用$ MAP迭代array1array2,使用$ filter filter array3 。最后,将array3与空数组进行比较,以匹配文档。

db.collection.aggregate([
  {
    "$addFields": {
      "array1": {
        "$map": {
          "input": "$array1",
          "as": "a1",
          "in": {
            id: "$a1.id",
            array2: {
              "$map": {
                "input": "$a1.array2",
                "as": "a2",
                "in": {
                  id: "$a2.id",
                  array3: {
                    "$filter": {
                      "input": "$a2.array3",
                      "as": "a3",
                      "cond": {
                        $eq: [
                          "$a3.status",
                          "done"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $match: {
      "array1.array2.array3": {
        $ne: []
      }
    }
  }
])

这是 mongo playground 供您参考。

Use $map to iterate array1 and array2, use $filter to filter array3. Finally compare array3 with empty array for document matching.

db.collection.aggregate([
  {
    "$addFields": {
      "array1": {
        "$map": {
          "input": "$array1",
          "as": "a1",
          "in": {
            id: "$a1.id",
            array2: {
              "$map": {
                "input": "$a1.array2",
                "as": "a2",
                "in": {
                  id: "$a2.id",
                  array3: {
                    "$filter": {
                      "input": "$a2.array3",
                      "as": "a3",
                      "cond": {
                        $eq: [
                          "$a3.status",
                          "done"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $match: {
      "array1.array2.array3": {
        $ne: []
      }
    }
  }
])

Here is the Mongo playground for your reference.

与往事干杯 2025-01-30 16:01:27

查询

  • 几乎与@Ray查询
  • $ MERGEOBJECTS允许我们不手工编写字段(如果MongoDB5+)也可以使用$ SETFIELD(如果代替ID,则您也有10个字段,这将有效不更改查询)

playmongo

aggregate(
[{"$set": 
   {"array1": 
     {"$map": 
       {"input": "$array1",
        "as": "a1",
        "in": 
         {"$mergeObjects": 
           ["$a1",
             {"array2": 
               {"$map": 
                 {"input": "$a1.array2",
                  "as": "a2",
                  "in": 
                   {"$mergeObjects": 
                     ["$a2",
                      {"array3": 
                       {"$filter": 
                        {"input": "$a2.array3",
                         "as": "a3",
                         "cond": {"$eq": ["$a3.status", "done"]}}}}]}}}}]}}}}}])

Query

  • almost the same as @ray query
  • $mergeObjects allows us to not write the fields by hand($setField can be used also if mongoDB5+) (if instead of id you also have 10 fields, this will work without changing the query)

Playmongo

aggregate(
[{"$set": 
   {"array1": 
     {"$map": 
       {"input": "$array1",
        "as": "a1",
        "in": 
         {"$mergeObjects": 
           ["$a1",
             {"array2": 
               {"$map": 
                 {"input": "$a1.array2",
                  "as": "a2",
                  "in": 
                   {"$mergeObjects": 
                     ["$a2",
                      {"array3": 
                       {"$filter": 
                        {"input": "$a2.array3",
                         "as": "a3",
                         "cond": {"$eq": ["$a3.status", "done"]}}}}]}}}}]}}}}}])
惯饮孤独 2025-01-30 16:01:27

我只是从


让我再次将代码放在这里,因为这更深

db.sample.aggregate([
  {
    $addFields: {
      newArray: "$array1"
    }
  },
  {
    "$match": {
      "newArray.array2.array3.status": "done"
    }
  },
  {
    "$unset": "newArray"
  }
])

mongo Playground

i just asnwered the same question from https://stackoverflow.com/a/75599962/9267467

the query is simply.
let me put my code here again because this is more deeper

db.sample.aggregate([
  {
    $addFields: {
      newArray: "$array1"
    }
  },
  {
    "$match": {
      "newArray.array2.array3.status": "done"
    }
  },
  {
    "$unset": "newArray"
  }
])

MONGO PLAYGROUND

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文