2011-02-23 61 views
20

我正在使用mongoDB其中我收集了以下格式。mongodb获取不同的记录

{"id" : 1 , name : x ttm : 23 , val : 5 } 
{"id" : 1 , name : x ttm : 34 , val : 1 } 
{"id" : 1 , name : x ttm : 24 , val : 2 } 
{"id" : 2 , name : x ttm : 56 , val : 3 } 
{"id" : 2 , name : x ttm : 76 , val : 3 } 
{"id" : 3 , name : x ttm : 54 , val : 7 } 

在该集合我已经查询,以获得在这样的递减顺序记录:

db.foo.find({"id" : {"$in" : [1,2,3]}}).sort(ttm : -1).limit(3) 

但它给出了相同的id = 1两项纪录,我想记录,例如,它给每id 1分的纪录。

mongodb有可能吗?

回答

25

mongodb中有一个distinct命令,它可以与查询结合使用。但是,我相信这只是为您指定的特定键值返回一个明确的值列表(例如,在您的情况下,您只能得到返回的id值),所以我不确定这会如何确切地为您提供所需的值需要整个文档 - 您可能需要使用MapReduce。

文档上的不同: http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct

+0

谢谢,是的,我想整个文件,但没有重复的id文件 – 2011-02-23 11:32:30

+0

'distinct(:id)'返回整个文件没有重复的id。 – Voldy 2011-02-23 12:30:27

+1

@Voldy - 我无法获得在mongo shell中工作的语法,给我一个语法错误? – AdaTheDev 2011-02-23 13:39:19

6

的问题是要提炼出3个匹配的记录下来,以一个查询中不包含有关如何匹配结果之间选择提供任何逻辑。

您的选项基本上是指定某种聚集逻辑(例如,为每列选择最大值或最小值),或运行选择明确查询并仅选择希望不同的字段。

querymongo.com为您翻译这些不同的查询(从SQL到MongoDB)做得很好。

例如,这个SQL:

SELECT DISTINCT columnA FROM collection WHERE columnA > 5 

返回因为这样的MongoDB:

db.runCommand({ 
    "distinct": "collection", 
    "query": { 
     "columnA": { 
      "$gt": 5 
     } 
    }, 
    "key": "columnA" 
}); 
2

如果你想使用JavaScript编写不同的结果在一个文件......你这是怎么做

cursor = db.myColl.find({'fieldName':'fieldValue'}) 

var Arr = new Array(); 
var count = 0; 

cursor.forEach(

function(x) { 

    var temp = x.id;  
var index = Arr.indexOf(temp);  
if(index==-1) 
    { 
    printjson(x.id); 
    Arr[count] = temp; 
     count++; 
    } 
}) 
4

我相信你可以使用聚合这样

collection.aggregate({ 
    $group : { 
     "_id" : "$id", 
     "docs" : { 
      $first : { 
      "name" : "$name", 
      "ttm" : "$ttm", 
      "val" : "$val", 
      } 
     } 
    } 
}); 
11

您想要使用聚合。你可以是这样做的:

db.test.aggregate([ 
    // each Object is an aggregation. 
    { 
     $group: { 
      originalId: {$first: '$_id'}, // Hold onto original ID. 
      _id: '$id', // Set the unique identifier 
      val: {$first: '$val'}, 
      name: {$first: '$name'}, 
      ttm: {$first: '$ttm'} 
     } 

    }, { 
     // this receives the output from the first aggregation. 
     // So the (originally) non-unique 'id' field is now 
     // present as the _id field. We want to rename it. 
     $project:{ 
      _id : '$originalId', // Restore original ID. 

      id : '$_id', // 
      val : '$val', 
      name: '$name', 
      ttm : '$ttm' 
     } 
    } 
]) 

这将是非常快速 ...〜90毫秒为100,000个文档我的测试数据库。

实施例:

db.test.find() 
// { "_id" : ObjectId("55fb595b241fee91ac4cd881"), "id" : 1, "name" : "x", "ttm" : 23, "val" : 5 } 
// { "_id" : ObjectId("55fb596d241fee91ac4cd882"), "id" : 1, "name" : "x", "ttm" : 34, "val" : 1 } 
// { "_id" : ObjectId("55fb59c8241fee91ac4cd883"), "id" : 1, "name" : "x", "ttm" : 24, "val" : 2 } 
// { "_id" : ObjectId("55fb59d9241fee91ac4cd884"), "id" : 2, "name" : "x", "ttm" : 56, "val" : 3 } 
// { "_id" : ObjectId("55fb59e7241fee91ac4cd885"), "id" : 2, "name" : "x", "ttm" : 76, "val" : 3 } 
// { "_id" : ObjectId("55fb59f9241fee91ac4cd886"), "id" : 3, "name" : "x", "ttm" : 54, "val" : 7 } 


db.test.aggregate(/* from first code snippet */) 

// output 
{ 
    "result" : [ 
     { 
      "_id" : ObjectId("55fb59f9241fee91ac4cd886"), 
      "val" : 7, 
      "name" : "x", 
      "ttm" : 54, 
      "id" : 3 
     }, 
     { 
      "_id" : ObjectId("55fb59d9241fee91ac4cd884"), 
      "val" : 3, 
      "name" : "x", 
      "ttm" : 56, 
      "id" : 2 
     }, 
     { 
      "_id" : ObjectId("55fb595b241fee91ac4cd881"), 
      "val" : 5, 
      "name" : "x", 
      "ttm" : 23, 
      "id" : 1 
     } 
    ], 
    "ok" : 1 
} 

优点:几乎可以肯定的最快方法。缺点:涉及使用复杂的聚集API。此外,它与文档的原始模式紧密耦合。尽管如此,有可能推广这一点。