是否有Mongo函数用于根据字段过滤所有嵌套/子文档



我在MongoDB中有一些文档有其他嵌套文档,所有文档都带有一个"活动的";领域例如:

{
"id": "PRODUCT1",
"name": "Product 1",
"active": true,
"categories": [
{
"id": "CAT-1",
"active": true,
"subcategories": [
{
"id": "SUBCAT-1",
"active": false
},
{
"id": "SUBCAT-2",
"active": true
}
]
},
{
"id": "CAT-2",
"active": false,
"subcategories": [
{
"id": "SUBCAT-3",
"active": true
}
]
}
]
}

有没有一种方法可以找到所有文档,但只保留";活动的";嵌套文档。

这是我想要的结果:

{
"id": "PRODUCT1",
"name": "Product 1",
"active": true,
"categories": [
{
"id": "CAT-1",
"active": true,
"subcategories": [
{
"id": "SUBCAT-2",
"active": true
}
]
}
]
}

知道我事先不知道文档模式。这就是为什么我需要一种条件通配符投影。。。(即*.active=true(。这是可能的还是必须在服务器端完成?

使用$redact

db.collection.aggregate(
[
{ $redact: {
$cond: {
if: { $eq:["$active", true] },
then: "$$DESCEND",
else: "$$PRUNE"
}
}
}
]
);

https://mongoplayground.net/p/7UMphkH5OWn

//actual code out from mongo shell 4.2 on windows
//sample document as shared in problem statement, query to find the document from //collection
> db.products.find().pretty();
{
"_id" : ObjectId("5f748ee5377e73757bb7ceac"),
"id" : "PRODUCT1",
"name" : "Product 1",
"active" : true,
"categories" : [
{
"id" : "CAT-1",
"active" : true,
"subcategories" : [
{
"id" : "SUBCAT-1",
"active" : false
},
{
"id" : "SUBCAT-2",
"active" : true
}
]
},
{
"id" : "CAT-2",
"active" : false,
"subcategories" : [
{
"id" : "SUBCAT-3",
"active" : true
}
]
}
]
}
//verify mongo shell version no. for reference
> db.version();
4.2.6
//using aggregate and $unwind you can query the inner array elements as shown below
> db.products.aggregate([
... {$unwind: "$categories"},
... {$unwind: "$categories.subcategories"},
... {$match:{"active":true,
...          "categories.active":true,
...          "categories.subcategories.active":true}}
... ]).pretty();
{
"_id" : ObjectId("5f748ee5377e73757bb7ceac"),
"id" : "PRODUCT1",
"name" : "Product 1",
"active" : true,
"categories" : {
"id" : "CAT-1",
"active" : true,
"subcategories" : {
"id" : "SUBCAT-2",
"active" : true
}
}
}
>

您可以通过几个$map$reduce$filter阶段来实现这一点。

db.collection.aggregate([
{
"$addFields": {
"categories": {
"$filter": {
"input": "$categories",
"cond": {
$eq: [
"$$this.active",
true
]
}
}
}
}
},
{
"$addFields": {
"categories": {
"$map": {
"input": "$categories",
"in": {
"$mergeObjects": [
"$$this",
{
"subcategories": {
"$filter": {
"input": "$$this.subcategories",
"cond": {
$eq: [
"$$this.active",
true
]
}
}
}
}
]
}
}
}
}
}
])

根据您的输入,执行以上操作将得到以下结果

[
{
"_id": ObjectId("5a934e000102030405000000"),
"active": true,
"categories": [
{
"active": true,
"id": "CAT-1",
"subcategories": [
{
"active": true,
"id": "SUBCAT-2"
}
]
}
],
"id": "PRODUCT1",
"name": "Product 1"
}
]

https://mongoplayground.net/p/fkkby-eibx2

最新更新