Мне нужно отфильтровать объект, который содержит только статус 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, если alteast один комментарий имеет статус C, который должен отображать только этот объект
Благодарю за ваш ответ. Я обновил свой ожидаемый результат
Для обработки inspection_data
вам понадобится $ filter. Ситуация усложняется, поскольку у вас есть несколько уровней вложенности, поэтому, прежде чем вы сможете применить условие $ в, вам нужно получить массив всех статусов для одного inspection_data
. Для этого вы можете использовать прямой путь, например "$$data.locationAspects.comments.status"
, но он возвращает массив таких массивов:
[ [ "C" ], [ "P" ] ], [ [ "P" ] ] ]
Таким образом, вам нужно сгладить этот массив, и этого можно достичь с помощью $ уменьшить и $ 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" ] } ] }
как мне получить здесь ответ
@Vishnu, если вы используете мангуста (на основе тегов), вы можете посмотреть здесь: mongoosejs.com/docs/api.html#Aggregate
Первоначально мне нужно сопоставить идентификатор проекта, как мне сопоставить здесь
Вам нужен дополнительный этап $ match, изменил мой ответ
У меня есть еще два сомнения в этом. В работе мы упомянули "C", но теперь я хочу напечатать, какой объект содержит "c" или "p", и у меня есть массив _id, поэтому, если данные проверки _id находятся в этом массиве, он должен печатать
@Vishnu изменил мой ответ, я не уверен в массиве случая _id, и он довольно значительно меняет начальную область этого вопроса, поэтому, пожалуйста, создайте еще один, касающийся массива _id
не могли бы вы вставить два документа (один, который должен и тот, который не следует печатать) и ожидаемый формат вывода?