MongoDB:'$ redact'仅用于匹配嵌入对象

时间:2015-05-05 22:57:31

标签: mongodb aggregation-framework

我有以下样式集合:

{ 
    "_id" : "5548d5ebb8157a53e9ceb9a4",
    "layers" : [
        { "_id" : "5548c97eb8157a53e9ceb9a0", "name" : "layer1"},
        { "_id" : "5548c97eb8157a53e9ceb9a1", "name" : "layer2"}
    ]
}
{ 
    "_id" : "5548d5ebb8157a778899b9a5",
    "layers" : [
        { "_id" : "5548c97eb8157a53e9ceb9a2", "name" : "layer1"},
        { "_id" : "5548c97eb8157a53e9ceb9a3", "name" : "layer2"}
    ]
}
...

我现在想要查询具有特定_id的图层。我想要的只是 一个匹配的图层对象数组。这是我试过的:

db.graphs.aggregate([
{ $match: { "layers._id": { $in: ["5548c97eb8157a53e9ceb9a1"] } } },
{ $redact : { $cond: 
    { if: 
        { $or : [
            { $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] },
            { $not : "$_id" }]
        },
        then: "$$DESCEND",
        else: "$$PRUNE" 
    } 
} }]);

不起作用 - 我得到一个空的结果。任何提示?

1 个答案:

答案 0 :(得分:2)

好的,我找到了解决方案,简短版本:

db.test.aggregate([ 
    { $match: { "layers._id": { $in: ["5548c97eb8157a53e9ceb9a1"] } } }, 
    { $redact : { $cond:
        { if:
            { $or : [
                { $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] },
                { $or : "$layers" }]
            },
            then: "$$DESCEND",
            else: "$$PRUNE"
        }
} }]);

说明:首先要了解$redact运算符向下调整匹配的文档,如树/图。这里的问题是顶级文档已经包含_id字段。因此,{ $not: "_id" }表达式的计算结果为false。在同一顶级,{ $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] }表达式也是如此,因为该id只能在嵌套的下一级找到。因此,顶级评估为false,“$$ PRUNE”完成而不是“$$ DESCEND”。

如果检查的级别具有layers属性(顶级,只有顶级级别)具有SimpleDateFormat formatter = `new SimpleDateFormat("yyyy-MM-dd hh:mm")`; 属性,则提供的解决方案会使测试成为真正的顶级传递。