MongoDB找到投影,匹配元素与$ ne

时间:2013-12-12 00:30:48

标签: node.js mongodb database

我有一个返回包含对象数组的对象的查询。在该对象数组中,有一些不应该被处理。这是一个与我所拥有的对象相似的对象:

{
    _id: 12345,
    data: [
        {
            state: 1,
            info: "abc"
        },{
            state: 2,
            info: "cde"
        },{
            state: 2,
            info: "efg"
        }
    ]
}

我想只显示 state 不等于 1 的对象。所以我想回到这样的事情:

{
    _id: 12345,
    data: [
        {
            state: 2,
            info: "cde"
        },{
            state: 2,
            info: "efg"
        }
    ]
}

可能有数百个具有数十个“子”对象的“主”对象。我尝试使用查询:

col.find({'data.info': {$in: [] }, {_id: 1, data: { $elemMatch: { state: {$ne: 1 } } } }, {}, callback);

但这只能给我这个:

{
    _id: 12345,
    data: [
        {
            state: 2,
            info: "cde"
        }
    ]
}

换句话说,$ elemMatch做它应该做的事情,但我需要得到不同的结果。那么有没有办法在一个查询中执行此操作或没有预处理结果(在任何进一步的代码读取数据之前删除条目)?

1 个答案:

答案 0 :(得分:1)

$elemMatch projection operator仅返回数组中的第一个匹配元素。

要过滤整个数组,MongoDB 2.2+中的最佳方法是使用聚合框架。或者,您也可以使用Map / Reduce或在应用程序代码中执行此操作。

聚合示例:

db.data.aggregate(

    // Initial match to limit number of documents
    { $match : {
        data: { $elemMatch: { state: {$ne: 1 } } }
    }},

    // Convert the data array into a stream of documents
    { $unwind: "$data" },

    // Limit to matching elements of the data array
    { $match : {
        "data.state": {$ne: 1 }
    }},

    // Re-group by original document _id
    { $group: {
        _id: "$_id",
        data: { $push: "$data" }
    }}
)

示例输出:

{
    "_id" : 12345,
    "data" : [
        {
            "state" : 2,
            "info" : "cde"
        },
        {
            "state" : 2,
            "info" : "efg"
        }
    ]
}