Найти с помощью arrayFilters, используя Mongoose - PullRequest
0 голосов
/ 26 сентября 2018

Мне нужно отфильтровать объект, который содержит только статус C в комментариях (если по крайней мере только комментарий имеет статус C, тогда этот объект должен быть напечатан) Я попытался использовать массив Filters, но не получил точный результат

 {
        "_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 голосов
/ 27 сентября 2018

Вам нужно $ фильтр для обработки inspection_data.Ситуация усложняется, поскольку у вас есть несколько уровней вложенности, поэтому, прежде чем вы сможете применить условие $ в , вам нужно получить массив всех статусов для одного inspection_data.Чтобы достичь этого, вы можете использовать прямой путь, например "$$data.locationAspects.comments.status", но он возвращает массив массивов, например:

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

Таким образом, вы должны сгладить этот массив, и этого можно достичь, используя $ redu и $ 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" ] } ] }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...