我在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)的原因。这可能还是需要在服务器端完成?
答案 0 :(得分:5)
使用$redact
。
db.collection.aggregate(
[
{ $redact: {
$cond: {
if: { $eq:["$active", true] },
then: "$$DESCEND",
else: "$$PRUNE"
}
}
}
]
);
答案 1 :(得分:1)
//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
}
}
}
>
答案 2 :(得分:0)
您将可以通过几个$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"
}
]