MongoDB聚合查询:查看值是否在数组中。

时间:2014-09-18 22:37:01

标签: mongodb mongodb-query aggregation-framework

我有一个ObjectIds数组,someOtherArray,需要将它们与聚合查询中的当前objectId进行比较。我相信我完成了大部分查询,但我不知道如何查看我当前的objectId是否在数组中,someOtherArray。我评论下面的代码我被困在哪里。

db.Collection.aggregate([
{
    $project: { 
        aField : {
            $map : {
                input: "$anArray",
                as : "arrayValue",
                //this is where I'm not sure on what to do.  I need something to return 
                //true or false on whether that item is in someOtherArray
                in: { $cond : {if: { $isInArray: [ $$arrayValue, someOtherArray] }, then: arrayValue, else: '' }}
            }
        } 
    }
}
]);

1 个答案:

答案 0 :(得分:1)

不确定这里的总体目的是什么,但基本上如果你只是想测试一个数组的内容是否与另一个提供的数组的内容(或者文档中的另一个数组字段)匹配,那么你可以测试一下$setIntersection运算符:

db.Collection.aggregate([
    { "$project": {
        "present": { "$gt": [
            { "$size": { "$setIntersection": [ "$anArray", someOtherArray ] } },
            0
        ]}
    }}
])

$setIntersection返回的内容只是“相同”和“设置”的元素,因此删除重复项。也许这就是你自己想要的,而不对结果进行$size测试,看看是否有任何东西。

如果您正在使用某种“匹配掩码”,其中元素从原始位置返回到它们与比较数组中的某些内容匹配的原始位置,那么您可以使用{{ 3}}每个操作:

db.Collection.aggregate([
    { "$project": {
        "altered": {
            "$map": {
                "input": "$anArray",
                "as": "orig",
                "in": {
                    "$cond": [
                        { "$anyElementTrue": {
                           "$map": {
                               "input": anotherArray
                               "as": "compare",
                               "in": { "$eq": [ "$$orig", "$$compare" ] }
                           }
                        }},
                        "$$orig",
                        false
                    ]
                }
            }
        }
    }}
])

这将返回一个与文档中原始长度相同的数组,但只有原始位置的“匹配”元素和所有其他元素表示为false。所以这里的“真值”测试是通过数组的每个元素进行比较,然后使用$map将其提炼为单个结果。

请记住,这些操作都是基于“真理”的概念,或者是以某种方式确定结果“组合”的手段。因此,除非您期望输出结果为false,否则您可能希望先过滤以删除那些永远不会包含匹配项的文档。这只是查询的$anyElementTrue运算符:

db.Collection.aggregate([
    { "$match": {
        "anArray": { "$in": someOtherArray }
    }}
])

这里的所有假设都是someOtherArray是一个外部声明的变量,它只是在这里用BSON表示“插入”它。要在文档中使用其他字段,您可以在所有情况下将其标记为"$someOtherArray",当然除了无法比较字段的$in管道的例外情况,并且需要您$match在您可以“过滤”该结果之前,该评估的“真实性”。