2014-09-01 62 views
0

我想获得所有匹配的值,使用$ 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 
     } 
    } 
}) ; 

我期待的结果是{values:[3,4,5,6,7,8,9]}。但是,真正的结果是{values:[4]}。 我看了mongo文档,我明白这是规范。

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

有什么想法?

回答

1

使用聚合:

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

您可以在$比赛增加更多的过滤条件,如果你想。

,因为你不能做到这一点使用$ elemMatch操作,MongoDB的医生说:

的$ elemMatch投影算限制数组 场被包含在查询结果的内容只包含与$ elemMatch条件匹配的数组 元素。

注意

The elements of the array are documents. 
+0

谢谢。我再考虑收集结构。 – sekitaka 2014-10-09 06:24:35

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] 
      ] 
     } 
    }} 
]) 
+0

谢谢。我了解如何使用'$ elemMatch'。 我再考虑收集结构。 – sekitaka 2014-10-09 06:25:23