如何在不使用 unwind 的情况下匹配 mongodb 中的数组字段和嵌套数组字段
how to match array field and nested array field in mongodb without using unwind
我的 json 数据将如下所示
{
"videoId": 29,
"videoComments": [
{
"comment": "awsome",
"userId": 15,
"commentTime": "2022-03-01T12:37:49.734Z",
"userName": "user1646127068323",
"deletedbyowner": "FALSE",
"_id": "621e139d8e4195079c86488",
"replyComments": [
{
"replyComment": "thank you",
"replyCommentTime": "2022-03-01T12:44:53.193Z",
"replyDeletedbyowner": "FALSE",
"_id": "621e154557fa7045e342540"
}
]
}
]
}
我需要满足下面提到的一些条件:
- 匹配“videoId”==“29”
- 然后匹配“videoComments.deletedbyowner”==“FALSE”
- 如果我匹配第二个条件,那么我需要匹配
“videoComments.replyComments.replyDeletedbyowner”==“假”
我不能使用 unwind,因为我的老板告诉我 unwind 是一项成本高昂的操作,它会影响应用程序的性能。所以在不使用 unwind 的情况下,我需要满足这些条件。
你能帮忙解决这个问题吗?
collection_name.find(
{ videoId : 29 },
{ videoComments : { $elemMatch : { deletedbyowner : "FALSE", $elemMatch: { replyDeletedbyowner: "FALSE"} } }
).pretty();
我想这就是您要找的。有关更多信息,请查看此 doc
查询
- 这会保留
videoId=29
的文档
- 只有
deletedbyowner="FALSE"
的元素
- 并且只有
replyDeletedbyowner="FALSE"
的元素
*这是聚合解决方案,我们还有 $elemMatch
和 $
来投影匹配的元素,但是这里你需要在嵌套数组上进行匹配,所以我认为你需要聚合,但我是不太确定。
aggregate(
[{"$match":{"$expr":{"$eq":["$videoId", 29]}}},
{"$set":
{"videoComments":
{"$map":
{"input":"$videoComments",
"in":
{"$cond":
[{"$ne":["$$this.deletedbyowner", "FALSE"]}, null,
{"$mergeObjects":
["$$this",
{"replyComments":
{"$filter":
{"input":"$$this.replyComments",
"cond":{"$eq":["$$reply.replyDeletedbyowner", "FALSE"]},
"as":"reply"}}}]}]}}}}},
{"$set":
{"videoComments":
{"$filter":
{"input":"$videoComments", "cond":{"$ne":["$$this", null]}}}}}])
我的 json 数据将如下所示
{
"videoId": 29,
"videoComments": [
{
"comment": "awsome",
"userId": 15,
"commentTime": "2022-03-01T12:37:49.734Z",
"userName": "user1646127068323",
"deletedbyowner": "FALSE",
"_id": "621e139d8e4195079c86488",
"replyComments": [
{
"replyComment": "thank you",
"replyCommentTime": "2022-03-01T12:44:53.193Z",
"replyDeletedbyowner": "FALSE",
"_id": "621e154557fa7045e342540"
}
]
}
]
}
我需要满足下面提到的一些条件:
- 匹配“videoId”==“29”
- 然后匹配“videoComments.deletedbyowner”==“FALSE”
- 如果我匹配第二个条件,那么我需要匹配 “videoComments.replyComments.replyDeletedbyowner”==“假”
我不能使用 unwind,因为我的老板告诉我 unwind 是一项成本高昂的操作,它会影响应用程序的性能。所以在不使用 unwind 的情况下,我需要满足这些条件。 你能帮忙解决这个问题吗?
collection_name.find(
{ videoId : 29 },
{ videoComments : { $elemMatch : { deletedbyowner : "FALSE", $elemMatch: { replyDeletedbyowner: "FALSE"} } }
).pretty();
我想这就是您要找的。有关更多信息,请查看此 doc
查询
- 这会保留
videoId=29
的文档
- 只有
deletedbyowner="FALSE"
的元素
- 并且只有
replyDeletedbyowner="FALSE"
的元素
*这是聚合解决方案,我们还有 $elemMatch
和 $
来投影匹配的元素,但是这里你需要在嵌套数组上进行匹配,所以我认为你需要聚合,但我是不太确定。
aggregate(
[{"$match":{"$expr":{"$eq":["$videoId", 29]}}},
{"$set":
{"videoComments":
{"$map":
{"input":"$videoComments",
"in":
{"$cond":
[{"$ne":["$$this.deletedbyowner", "FALSE"]}, null,
{"$mergeObjects":
["$$this",
{"replyComments":
{"$filter":
{"input":"$$this.replyComments",
"cond":{"$eq":["$$reply.replyDeletedbyowner", "FALSE"]},
"as":"reply"}}}]}]}}}}},
{"$set":
{"videoComments":
{"$filter":
{"input":"$videoComments", "cond":{"$ne":["$$this", null]}}}}}])