按数组、Mongodb 中的字段值过滤文档

Upv*_*ote 3 mongodb mongodb-query aggregation-framework node-mongodb-native

收藏:

[{
    _id: 'Foo',
    plugs: [
        { type: 'CE', code: 12 },
        { type: 'SH': code: 34 }
    ]
},{
    _id: 'Bar',
    plugs: [
        { type: 'T2', code: 23 },
        { type: 'T2': code: 43 }
    ]
}]
Run Code Online (Sandbox Code Playgroud)

在插头阵列中可能存在具有相同类型的条目。当我进行聚合时,我想按插头类型过滤文档。例如,仅返回包含 T2 类型插头的文档。我怎样才能在 mongodb 中做到这一点?我知道 $in 查询,但这仅适用于简单的值数组。

Nei*_*unn 5

当预期只有一个匹配时,基于普通的.find()投影效果很好,但聚合框架是目前唯一将从数组返回“多个”结果的东西:

db.collection.aggregate([
    // Still makes sense to "filter" the documents
    { "$match": { "plugs.type": "T2" } },
    { "$unwind": "$plugs" },
    // This actually "filters" the array content
    { "$match": { "plugs.type": "T2" } },
    { "$group": {
        "_id": "$_id",
        "plugs": { "$push": "$plugs" }
    }}
])
Run Code Online (Sandbox Code Playgroud)

或者,即使使用 MongoDB 2.6 或更高版本,您也可以使用“set”约束下的“唯一”条目来执行此操作:

db.collection.aggregate([
    { "$match": { "plugs.type": "T2" } },
    { "$project": {
        "plugs": {
            "$setDiffernce": [
                { "$map": {
                     "input": "$plugs",
                     "as": "el",
                     "in": {
                         "$cond": [
                             { "$eq": [ "$$el.type", "T2" ] },
                             "$$el",
                             false
                         ]
                     }
                }},
                [false]
            ]
        }
    }}
])
Run Code Online (Sandbox Code Playgroud)

但实际上你只是在谈论“文档匹配”而不是“元素过滤”,所以这里的聚合框架是多余的。只需匹配文档即可:

db.collection.find({ "plugs.type": "T2" })
Run Code Online (Sandbox Code Playgroud)

这只会返回至少一个元素与条件匹配的“文档”。这是对查询模式在 MongoDB 中实际工作方式的基本了解的一部分。

这里的基本类型使用“点符号”来指定文档标识的“部分”。这又是 MongoDB 查询工作原理的基本部分。