用嵌套的条件查询mongodb

时间:2013-01-06 03:45:46

标签: mongodb

{
   "name": "comments",
   "rid": 456,

   "refs": [
     {
       "no": 1,
       "info": "this is first"  
    },
     {
       "no": 2,
       "info": "this is second" 
    },
     {
       "no": 3,
       "info": "this is third"  
    } 
  ] 
}
{
   "name": "comments",
   "rid": 321,

   "refs": [
     {
       "no": 1,
       "info": "this is first-h"  
    },
     {
       "no": 2,
       "info": "this is second-h" 
    },
     {
       "no": 3,
       "info": "this is third-h"  
    } 
  ] 
}

假设我有一个像上面这样的文档结构。我需要得到摆脱456但不是2的数组。所以,我只想得到数组

     {
       "no": 2,
       "info": "this is second" 
    }

我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

除了JohnnyHK使用positional operator之外,还有一些方法可以在MongoDB 2.2 +中解决这个问题:

方法#1:使用$elemMatch投影

$elemMatch projection可用于包含数组的单个匹配元素。默认情况下,结果还包含文档_id,但如果不需要,您可以将其排除在外:

db.comments.find(
    { rid: 456 },
    { _id:0, refs: { $elemMatch: { no: 2 } }}
)

示例输出:

{ "refs" : [ { "no" : 2, "info" : "this is second" } ] }

方法#2:使用聚合框架

Aggregation Framework包括$unwind数组的运算符和$match文档条件。这种方法比使用$elemMatch投影更具灵活性,因为现在可以返回每个数组的多个匹配项。

db.comments.aggregate(

    // Find matching documents of interest (can use an index)
    { $match: { rid: 456 }},

    // Create stream of documents based on the `refs` array
    { $unwind: "$refs" },

    // Match the specific refs element(s) of interest
    { $match: { "refs.no" : 2 }},

    // Project the desired output
    { $project: {
        _id: 0,
        no: "$refs.no",
        info: "$refs.info"
    }}
)

示例输出:

{
    "result" : [
        {
            "no" : 2,
            "info" : "this is second"
        }
    ],
    "ok" : 1
}

答案 1 :(得分:1)

您可以使用dot notation查找所需的文档,并使用$位置运算符在结果中仅包含匹配的数组元素:

 
 db.test.find({rid: 456, 'refs.no': 2}, {_id: 0, 'refs.$': 1})

返回:

 
{ "refs": [ { "no": 2, "info": "this is second" } ] }