Mongodb 如果只有嵌套文档匹配结果,是否可以排除根文档?
Mongodb Is it possible to exclude the root document if only a nested document matches the result?
我有一组文档,其中包含同一文档的一组嵌套修订版。我需要执行 returns 仅匹配集的搜索查询,包括匹配的父项。以下是数据的简化示例。
{
"title_number": "46345734",
"status": "applied",
"updated": "02/04/2022",
"rev_num": 1,
"revs": [
{
"title_number": "46345734",
"status": "unapplied",
"updated": "02/06/2022",
"rev_num": 2
}]
},
{
"title_number": "46345802",
"status": "unapplied",
"updated": "02/05/2022",
"rev_num": 1,
"revs": [
{
"title_number": "46345802",
"status": "applied",
"updated": "02/05/2022",
"rev_num": 2
},
{
"title_number": "46345802",
"status": "applied",
"updated": "02/06/2022",
"rev_num": 3
}]
}
在一个查询中,我想查找状态为“未应用”的所有文档,只返回与状态匹配的嵌套文档,如果也匹配则保留或删除父文档。
下面是我期望查询最初看起来如何的示例,以及 运行 根据提供的示例数据时的预期结果。
titles.find({
"$and": [{
"$or": [
{"status": "applied"},
{"revs.status": "applied"}
]
}]
})
预期(想要)结果
{
"title_number": "46345734",
"status": "applied",
"updated": "02/04/2022",
"rev_num": 1,
"revs": [],
},
{
"title_number": "46345802",
"status": "applied",
"updated": "02/05/2022",
"rev_num": 2
},
{
"title_number": "46345802",
"status": "applied",
"updated": "02/06/2022",
"rev_num": 3
}
在第一个结果中,父状态匹配,但子不匹配,因此只返回父。在第二个结果中,父级不匹配,但是,两个嵌套文档匹配,所以只返回它们。
在阅读了大量关于聚合、元素匹配等的帖子后,我已经能够得到一些零碎的信息,但我的情况似乎非常明显或相当独特。
在此先感谢您的帮助。
使用 aggregate
并首先 $filter revs with applied status
and then $push 应用文档来分隔数组,然后 revs
应用到另一个数组,最后将两个数组混合为一个。
你可以在这里测试mongodb playground
titles.aggregate([
{
"$addFields": {
"revs": {
$filter: {
input: "$revs",
as: "rev",
cond: {
$eq: [
"$$rev.status",
"applied"
]
}
}
}
}
},
{
$group: {
_id: null,
applied_doc: {
$push: {
$cond: [
{
$eq: [
"$status",
"applied"
]
},
{
_id: "_id",
title_number: "$title_number",
status: "$status",
updated: "$updated",
rev_num: "$rev_num",
revs: "$revs"
},
"$$REMOVE"
]
}
},
applied_sub_doc: {
$push: "$revs"
}
},
},
// flatten array in $applied_sub_doc prop
{
$set: {
applied_sub_doc: {
$reduce: {
input: "$applied_sub_doc",
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this"
],
},
},
},
},
},
{
$project: {
mixedDocs: {
$concatArrays: [
"$applied_doc",
"$applied_sub_doc"
],
},
},
},
{
$unwind: "$mixedDocs",
},
{
$replaceWith: "$mixedDocs",
},
])
我有一组文档,其中包含同一文档的一组嵌套修订版。我需要执行 returns 仅匹配集的搜索查询,包括匹配的父项。以下是数据的简化示例。
{
"title_number": "46345734",
"status": "applied",
"updated": "02/04/2022",
"rev_num": 1,
"revs": [
{
"title_number": "46345734",
"status": "unapplied",
"updated": "02/06/2022",
"rev_num": 2
}]
},
{
"title_number": "46345802",
"status": "unapplied",
"updated": "02/05/2022",
"rev_num": 1,
"revs": [
{
"title_number": "46345802",
"status": "applied",
"updated": "02/05/2022",
"rev_num": 2
},
{
"title_number": "46345802",
"status": "applied",
"updated": "02/06/2022",
"rev_num": 3
}]
}
在一个查询中,我想查找状态为“未应用”的所有文档,只返回与状态匹配的嵌套文档,如果也匹配则保留或删除父文档。
下面是我期望查询最初看起来如何的示例,以及 运行 根据提供的示例数据时的预期结果。
titles.find({
"$and": [{
"$or": [
{"status": "applied"},
{"revs.status": "applied"}
]
}]
})
预期(想要)结果
{
"title_number": "46345734",
"status": "applied",
"updated": "02/04/2022",
"rev_num": 1,
"revs": [],
},
{
"title_number": "46345802",
"status": "applied",
"updated": "02/05/2022",
"rev_num": 2
},
{
"title_number": "46345802",
"status": "applied",
"updated": "02/06/2022",
"rev_num": 3
}
在第一个结果中,父状态匹配,但子不匹配,因此只返回父。在第二个结果中,父级不匹配,但是,两个嵌套文档匹配,所以只返回它们。
在阅读了大量关于聚合、元素匹配等的帖子后,我已经能够得到一些零碎的信息,但我的情况似乎非常明显或相当独特。
在此先感谢您的帮助。
使用 aggregate
并首先 $filter revs with applied status
and then $push 应用文档来分隔数组,然后 revs
应用到另一个数组,最后将两个数组混合为一个。
你可以在这里测试mongodb playground
titles.aggregate([
{
"$addFields": {
"revs": {
$filter: {
input: "$revs",
as: "rev",
cond: {
$eq: [
"$$rev.status",
"applied"
]
}
}
}
}
},
{
$group: {
_id: null,
applied_doc: {
$push: {
$cond: [
{
$eq: [
"$status",
"applied"
]
},
{
_id: "_id",
title_number: "$title_number",
status: "$status",
updated: "$updated",
rev_num: "$rev_num",
revs: "$revs"
},
"$$REMOVE"
]
}
},
applied_sub_doc: {
$push: "$revs"
}
},
},
// flatten array in $applied_sub_doc prop
{
$set: {
applied_sub_doc: {
$reduce: {
input: "$applied_sub_doc",
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this"
],
},
},
},
},
},
{
$project: {
mixedDocs: {
$concatArrays: [
"$applied_doc",
"$applied_sub_doc"
],
},
},
},
{
$unwind: "$mixedDocs",
},
{
$replaceWith: "$mixedDocs",
},
])