从集合中获取基于单个字段的唯一文档的最简单方法是什么。
我知道我可以使用db.collections.distrinct来获取字段的所有不同值的数组,但我想获得一个字段的每个不同值的第一个(或实际上任何一个)文档。
e.g。如果数据库包含:
{number:1, data:'Test 1'}
{number:1, data:'This is something else'}
{number:2, data:'I'm bad at examples'}
{number:3, data:'I guess there\'s room for one more'}
它将返回(基于number
唯一:
{number:1, data:'Test 1'}
{number:2, data:'I'm bad at examples'}
{number:3, data:'I guess there\'s room for one more'}
编辑:我应该补充一点,服务器正在运行Mongo 2.0.8,因此没有聚合,并且比group支持的结果更多。
答案 0 :(得分:2)
更新到2.4并使用聚合:)
由于涉及过多的繁文缛节,当你真的需要坚持使用旧版本的MongoDB时,可以使用MapReduce。
在MapReduce中,map函数将集合的每个文档转换为新文档和独特键。 reduce函数用于将具有相同distincitve键的文档合并为一个。
您的地图功能会按原样发出您的文档,并将数字字段作为唯一键。它看起来像这样:
var mapFunction = function(document) {
emit(document.number, document);
}
你的reduce函数接收具有相同键的文档数组,并且应该以某种方式将它们转换为一个文档。在这种情况下,它只会丢弃除第一个文档以外的所有文档:
var reduceFunction = function(key, documents) {
return documents[0];
}
不幸的是,MapReduce存在一些问题。它不能使用索引,因此对集合中的每个文档至少执行两个javascript函数(可以通过使用query-argument将某些文档预先排除到mapReduce命令来限制它)。当你有一个大型集合时,这可能需要一段时间。您也无法完全控制MapReduce创建的文档的形成方式。它们总是有两个字段,_id
带有密钥,value
带有您为密钥返回的文档。
MapReduce也很难调试故障排除。
tl; dr:更新到2.4