2014-04-07 296 views
0

我有这个漂亮的Json,我试着用强大的mongodb查询来获得所有带有file_id 12的注释....所以这就是我想要的[4,5,7,10 ,11,15]。嵌套查询Mongodb

我试着用此查询,但FILE_ID它是完全由发动机忽略:

db.collection.distinct("changes.comments", 
     {"my_uuid":"bf48e757-1a65-4546-bf24-2bb001effddd", 
     "changes":{$elemMatch:{file_id:12}} } 
) 

输出:

{ 
    "_id" : ObjectId("5342bf796b03d7ffc834afcc"), 
    "my_uuid" : "bf48e757-1a65-4546-bf24-2bb001effddd", 
    "changes" : [ 
     { 
      "file_id" : 12, 
      "version" : 1, 
      "comments" : [ 
       4, 
       5, 
       7 
      ], 
      "lastseen" : 1394640549 
     }, 
     { 
      "file_id" : 12, 
      "version" : 2, 
      "comments" : [ 
       10, 
       11, 
       15 
      ], 
      "lastseen" : 1394640511 
     }, 
     { 
      "file_id" : 234, 
      "version" : 1, 
      "comments" : [ 
       100, 
       110, 
       150 
      ], 
      "lastseen" : 1394640555 
     } 
    ] 
} 

在此先感谢

回答

2

可以使用aggregation framework来实现你的目标。尽管查询看起来很复杂,但是一旦你掌握了它,这很简单。

db.collection.aggregate([ 
    // Get only documents where "my_uuid" equals "bf48e757-1a65-4546-bf24-2bb001effddd" 
    {"$match":{"my_uuid":"bf48e757-1a65-4546-bf24-2bb001effddd"}}, 
    // Unwind the "changes" array 
    {"$unwind":"$changes"}, 
    // Get only elements of the "changes" array where "file_id" equals 12 
    {"$match":{"changes.file_id":12}}, 
    // Unwind the "comments" array 
    {"$unwind":"$changes.comments"}, 
    // Group by _id and add the comments to array only if not already present 
    {"$group":{_id:"$_id", comments:{$addToSet:"$changes.comments"}}}, 
    // Cleanup the output 
    {"$project":{_id:0, comments:1}} 
]) 

输出:

{ 
     "result" : [ 
       { 
         "comments" : [ 
           4, 
           5, 
           7, 
           10, 
           11, 
           15 
         ] 
       } 
     ], 
     "ok" : 1 
} 

编辑:包括my_uuid的结果是相当直接的。我们只需按my_uuid,而不是_id

db.collection.aggregate([ 
    {"$match":{"my_uuid":"bf48e757-1a65-4546-bf24-2bb001effddd"}}, 
    {"$unwind":"$changes"}, 
    {"$match":{"changes.file_id":12}}, 
    {"$unwind":"$changes.comments"}, 
    {"$group":{_id:"$my_uuid", comments:{$addToSet:"$changes.comments"}}}, 
    {"$project":{_id:0, my_uuid:"$_id", comments:1}} 
]) 
+0

是的,谢谢你....如果我还要在结果中添加my_uuid,怎么办? – magemello

+0

是集合中唯一的'my_uuid'? –

+0

你能否提供一个my_uuid作为唯一的例子,而不是? – magemello

0

目前存在从一个数组拉出只有匹配的文件没有直接的方法。 $ elemMatch操作符只会确保阵列中至少有一个文档符合您提供的条件。但是,查询将始终返回整个文档。达到你所寻找的一种方式是 -

db.sample4.aggregate({$unwind:"$changes"},{$match:{"changes.file_id":12}},{$project:{"changes.comments":1,"_id":0}}); 

这些主题涵盖计算器,其中的map-reduce方法,以及上市来实现这一here。如果要求返回第一个匹配文档,则可以使用changes.comments.$:1例如。 - db.sample4.find({"changes":{$elemMatch:{"file_id":12}} },{"changes.comments.$":1})