mongodb 获取不同的记录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5089162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
mongodb get distinct records
提问by Swapnil Sonawane
I am using mongoDB
in which I have collection of following format.
我正在使用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 }
On that collection I have queried to get records in descending order like this:
在该集合中,我查询以降序获取记录,如下所示:
db.foo.find({"id" : {"$in" : [1,2,3]}}).sort(ttm : -1).limit(3)
But it gives two records of same id = 1
and I want records such that it gives 1 record per id
.
但它给出了两个相同的记录,id = 1
我想要这样的记录,每个id
.
Is it possible in mongodb?
在mongodb中有可能吗?
采纳答案by AdaTheDev
There is a distinct
command in mongodb, that can be used in conjunction with a query. However, I believe this just returns a distinct list of values for a specific key you name (i.e. in your case, you'd only get the id values returned) so I'm not sure this will give you exactly what you want if you need the whole documents - you may require MapReduce instead.
distinct
mongodb 中有一个命令,可以与查询结合使用。但是,我相信这只会为您命名的特定键返回一个不同的值列表(即在您的情况下,您只会得到返回的 id 值)所以我不确定这是否会为您提供您想要的需要整个文档 - 您可能需要 MapReduce。
Documentation on distinct: http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct
关于不同的文档:http: //www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct
回答by robert
You want to use aggregation. You could do that like this:
您想使用聚合。你可以这样做:
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'
}
}
])
This will be veryfast... ~90ms for my test DB of 100,000 documents.
这将非常快......对于我的 100,000 个文档的测试数据库,大约为 90 毫秒。
Example:
例子:
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
}
PROS: Almost certainly the fastest method.
优点:几乎可以肯定是最快的方法。
CONS: Involves use of the complicated Aggregation API. Also, it is tightly coupled to the original schema of the document. Though, it may be possible to generalize this.
缺点:涉及使用复杂的聚合 API。此外,它与文档的原始模式紧密耦合。不过,有可能概括这一点。
回答by Sajjad Ashraf
I believe you can use aggregate like this
我相信你可以像这样使用聚合
collection.aggregate({
$group : {
"_id" : "$id",
"docs" : {
$first : {
"name" : "$name",
"ttm" : "$ttm",
"val" : "$val",
}
}
}
});
回答by robertjmoore
The issue is that you want to distill 3 matching records down to one without providing any logic in the query for how to choose between the matching results.
问题是您希望将 3 个匹配记录提取为一个,而无需在查询中提供任何关于如何在匹配结果之间进行选择的逻辑。
Your options are basically to specify aggregation logic of some kind (select the max or min value for each column, for example), or to run a select distinct query and only select the fields that you wish to be distinct.
您的选项基本上是指定某种聚合逻辑(例如,为每列选择最大值或最小值),或者运行选择不同的查询并仅选择您希望不同的字段。
querymongo.comdoes a good job of translating these distinct queries for you (from SQL to MongoDB).
querymongo.com在为您翻译这些不同的查询(从 SQL 到 MongoDB)方面做得很好。
For example, this SQL:
例如,这个 SQL:
SELECT DISTINCT columnA FROM collection WHERE columnA > 5
Is returned as this MongoDB:
作为这个 MongoDB 返回:
db.runCommand({
"distinct": "collection",
"query": {
"columnA": {
"$gt": 5
}
},
"key": "columnA"
});
回答by rajibdotnet
If you want to write the distinct result in a file using javascript...this is how you do
如果你想使用 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++;
}
})