Mongo找到了独特的结果

时间:2013-09-16 12:51:14

标签: mongodb pymongo

从集合中获取基于单个字段的唯一文档的最简单方法是什么。

我知道我可以使用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支持的结果更多。

1 个答案:

答案 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