如何搜索嵌入式数组

时间:2014-09-01 07:57:02

标签: mongodb mongodb-query aggregation-framework

我希望使用$ elemMatch获得所有匹配值。

// create test data
db.foo.insert({values:[0,1,2,3,4,5,6,7,8,9]})
db.foo.find({},{
    'values':{
        '$elemMatch':{
            '$gt':3
         }
    }
}) ;

我的预期结果是{值:[3,4,5,6,7,8,9]}。但是,真正的结果是{值:[4]}。 我读过mongo文档,我知道这是规范。

如何搜索多值? 而且,我使用'skip'和'limit'。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

使用聚合:

db.foo.aggregate([
{$unwind:"$values"},
{$match:{"values":{$gt:3}}},
{$group:{"_id":"$_id","values":{$push:"$values"}}}
])

如果您愿意,可以在$ match中添加更多过滤条件。

你无法使用$ elemMatch运算符来实现这一点,因为mongoDB doc说:

  

$ elemMatch投影运算符限制数组的内容   查询结果中包含的字段仅包含数组   与$ elemMatch条件匹配的元素。

     
    

注意

The elements of the array are documents.
  

答案 1 :(得分:0)

如果仔细查看$elemMatch上的文档或查询positional $运算符的对应文件,那么您会看到此类“投影”仅返回“第一个”匹配元素

您正在寻找的实际上是“操纵”文档内容,您想要“过滤”文档中数组的内容而不是返回原始或“匹配”元素,因为只能有一个匹配

对于真正的“过滤”,您需要聚合框架,因为文档操作有更多支持:

db.foo.aggregate([

    // No point selecting documents that do not match your condition
    { "$match": { "values": { "$gt": 3 } } },

    // Unwind the array to de-normalize as documents
    { "$unwind": "$values },

    // Match to "filter" the array
    { "$match": { "values": { "$gt": 3 } } },

    // Group by to the array form
    { "$group": {
        "_id": "$_id",
        "values": { "$push": "$values" }
    }}
])

或者从2.6及更高版本开始使用MongoDB的现代版本,其中数组值是“唯一的”,您可以这样做:

db.foo.aggregate([
    { "$project": {
        "values": {
            "$setDifference": [
                { "$map": {
                    "input": "$values",
                    "as": "el",
                    "in": {
                        "$cond": [
                            { "$gt": [ "$$el", 3 ] },
                            "$$el",
                            false
                        ]
                    }
                }},
                [false]
            ]
        }
    }}
])