在 Mongo 数据库 (Shell) 中查询和过滤嵌套数组

Querying and Filtering Nested Arrays in Mongo DB (Shell)

我的 mongo collection

中有以下 3 个文件
{ 
    "_id" : {
        "docId" : "089b0b4e-3096-4111-b074-a6713f58bfab"
    }, 
    "items" : [
        {
            "products" : [ 
                {
                    "_id" : {
                        "productId" : null
                    }
                }, 
                {
                    "_id" : {
                        
                    }
                }, 
                {
                    "_id" : {
                        "productId" : "c26672a8-b5b1-42bf-8ec5-476db4bd3975"
                    }
                }
            ]
        },
        {
            "products" : [
                {
                    "_id" : {
                        "productId" : "681a8658-768a-4665-bf51-ef556f881646"
                    }
                }, 
                {
                    "_id" : {
                        
                    }
                }, 
                {
                    "_id" : null
                }
            ]
        }
    ]
},
{ 
    "_id" : {
        "docId" : "32d2e389-d377-4552-a3c6-dc52d2abaa6c"
    }, 
    "items" : [
        {
            "products" : [ 
                {
                    "_id" : {
                        "productId" : null
                    }
                }, 
                {
                    "_id" : {
                        
                    }
                }, 
                {
                    "_id" : {
                        "productId" : "bea6baef-d8c0-4e7c-9b49-98af4a4f53e8"
                    }
                }
            ]
        },
        {
            "products" : [
                {
                    "_id" : {
                        "productId" : null
                    }
                }, 
                {
                    "_id" : {
                        "productId" : "8d598e72-cd72-4d3b-aa2c-1278ad4acce1"
                    }
                }, 
                {
                    "_id" : null
                }
            ]
        }
    ]
},
{ 
    "_id" : {
        "docId" : "69effab9-2071-4c9b-a49d-dd38384991d9"
    }, 
    "items" : [
        {
            "products" : [ 
                {
                    "_id" : {
                        "productId" : null
                    }
                }, 
                {
                    "_id" : {
                        
                    }
                }
            ]
        }
    ]
}

假设有效的 productId 存在且不为空,我需要查询 return 仅包含至少一个有效 productId 的文档,同时产品数组应仅包含那些有效的产品文件只有这样: (请注意,只有 2 个文档 return 编辑了总共 4 个产品)

{ 
    "_id" : {
        "docId" : "089b0b4e-3096-4111-b074-a6713f58bfab"
    }, 
    "items" : [
        {
            "products" : [ 
                {
                    "_id" : {
                        "productId" : "c26672a8-b5b1-42bf-8ec5-476db4bd3975"
                    }
                }
            ]
        },
        {
            "products" : [
                {
                    "_id" : {
                        "productId" : "681a8658-768a-4665-bf51-ef556f881646"
                    }
                }
            ]
        }
    ]
},
{ 
    "_id" : {
        "docId" : "32d2e389-d377-4552-a3c6-dc52d2abaa6c"
    }, 
    "items" : [
        {
            "products" : [ 
                {
                    "_id" : {
                        "productId" : "bea6baef-d8c0-4e7c-9b49-98af4a4f53e8"
                    }
                }
            ]
        },
        {
            "products" : [
                {
                    "_id" : {
                        "productId" : "8d598e72-cd72-4d3b-aa2c-1278ad4acce1"
                    }
                }
            ]
        }
    ]
}

我试过了,但似乎不起作用

collection.find({    
    "items": {
         $elemMatch: {
             "products": {
                 $elemMatch: {
                    "_id.productId": { $exists: true, $ne: null }
                 }
             }
         }   
    }
})

find方法不行吗?

您可以使用聚合

  • 您的 productId 在嵌套数组中。我们使用 $map 循环它。
  • $filter 使用条件
  • 过滤对象
  • 如果您的产品数组有任何匹配条件的元素($anyElementTrue),我们会在 $mergeObjects
  • 的帮助下添加另一个变量 hasProductId 是真还是假
  • 条件是productId不能为nullundefined
  • 您将在文档
  • 的每个对象中得到hasProductId
  • $match 帮助,如果任何事情都是真的,那么得到文件
  • $project 帮助删除临时字段 $hasProductId

这是代码

db.collection.aggregate([
  {
    $project: {
      items: {
        "$map": {
          "input": "$items",
          "in": {
            products: {
              "$filter": {
                "input": "$$this.products",
                "as": "product",
                "cond": {
                  "$and": [
                    {
                      $ne: [
                        "$$product._id.productId",
                        null
                      ],
                      
                    },
                    {
                      $ne: [
                        "$$product._id.productId",
                        undefined
                      ],
                      
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$match": {
      "items.products": {
        $ne: []
      }
    }
  }
])

工作Mongo playground