使用Mongoose使用arrayFilters查找

时间:2018-09-26 11:02:41

标签: node.js mongodb mongoose filter

我必须过滤注释中仅包含状态C的对象(如果至少注释中的状态为C,则仅应打印该对象)我尝试使用数组过滤器,但未获得确切结果

 {
        "_id" : ObjectId("5b8f84379f432a42383a85bb"),
        "projectID" : ObjectId("00000000e614c33390237ce3"),
        "inspection_data" : [ 
            {
                "locationAspects" : [ 
                    {
                        "aspectname" : "Ground floor",
                        "comments" : [ 
                            {
                     "status" :"C",
                                "comment" : [ 
                                    "good"
                                ],
                                "_id" : ObjectId("5b8f84379f16400f884d9974")
                            }
                        ],
                        "_id" : ObjectId("5b8f84379f16400f884d9975")
                    }, 
                    {
                        "aspectname" : "Second floor",
                        "comments" : [ 
                            {
                               "status" :"P",
                                "comment" : [ 
                                    "nothing"
                                ],

                                "_id" : ObjectId("5b8f84379f16400f884d9971")
                            }
                        ],
                        "_id" : ObjectId("5b8f84379f16400f884d9972")
                    }, 
                ],
                "published_date" : ISODate("2018-09-05T07:22:31.017Z"),
                "_id" : ObjectId("5b8f84379f16400f884d9976")
            },
          {
                "locationAspects" : [ 
                    {
                        "aspectname" : "Ground floor",
                        "comments" : [ 
                            {
                     "status" :"P",
                                "comment" : [ 
                                    "good"
                                ],
                                "_id" : ObjectId("5b8f84379f16400f884d9974")
                            }
                        ],
                        "_id" : ObjectId("5b8f84379f16400f884d9975")
                    } 
                ],
                "published_date" : ISODate("2018-09-05T07:22:31.017Z"),
                "_id" : ObjectId("5b8f84379f16400f884d9976")
            }
        ]

现在检查数据具有两个对象,但一个对象仅包含注释状态c,因此应打印

预期结果

[ {
                    "locationAspects" : [ 
                        {
                            "aspectname" : "Ground floor",
                            "comments" : [ 
                                {
                         "status" :"C",
                                    "comment" : [ 
                                        "good"
                                    ],
                                    "_id" : ObjectId("5b8f84379f16400f884d9974")
                                }
                            ],
                            "_id" : ObjectId("5b8f84379f16400f884d9975")
                        }, 
                        {
                            "aspectname" : "Second floor",
                            "comments" : [ 
                                {
                                   "status" :"P",
                                    "comment" : [ 
                                        "nothing"
                                    ],

                                    "_id" : ObjectId("5b8f84379f16400f884d9971")
                                }
                            ],
                            "_id" : ObjectId("5b8f84379f16400f884d9972")
                        }, 
                    ],
                    "published_date" : ISODate("2018-09-05T07:22:31.017Z"),
                    "_id" : ObjectId("5b8f84379f16400f884d9976")
                }]

仅当对象至少要显示一个注释状态为C时,以上对象才具有状态C

1 个答案:

答案 0 :(得分:0)

您需要$filter处理inspection_data。由于您具有多层嵌套,因此事情变得越来越复杂,因此在应用$in条件之前,您需要获取单个inspection_data的所有状态的数组。为此,您可以使用像"$$data.locationAspects.comments.status"这样的直接路径,但是它会返回这样的数组数组:

[ [ "C" ], [ "P" ] ], [ [ "P" ] ] ]

因此,您必须弄平该数组,并且可以使用$reduce$concatArrays来实现。试试:

db.col.aggregate([
    { $match: { projectID: ObjectId("00000000e614c33390237ce3") } },
    {
        $project: {
            filtered_inspection_data: {
                $filter: {
                    input: "$inspection_data",
                    as: "data",
                    cond: { 
                        $let: {
                            vars: {
                                statuses: {
                                    $reduce: { 
                                        input: "$$data.locationAspects.comments.status", 
                                        initialValue: [], 
                                        in: { $concatArrays: [ "$$this", "$$value" ] } 
                                    } 
                                }
                            },
                            in: { $in: [ "C", "$$statuses" ] }
                        }
                    }
                }
            }
        }
    }
])

编辑:为匹配"C""P",您可以将{ $in: [ "C", "$$statuses" ] }替换为以下行

{ $or: [ { $in: [ "C", "$$statuses" ] }, { $in: [ "P", "$$statuses" ] } ] }