检索"最新的"文献?

时间:2015-02-03 01:53:10

标签: mongodb mongodb-query

我是MongoDB的新手,拥有一个包含字段regionIdtypeIdtimestamp等文档的集合。

是否有一种有效的方法来检索"最新的"基于regionId的{​​{1}}和typeId对的文档?也就是说,如果文档中包含timestampregionId,则只会有一个结果,并且它不会比未选择的文档具有更小的typeId

我尝试使用timestamp并使用以下聚合管道对此进行索引:

{ regionId: 1, typeId: 1, timestamp: -1 }

我无法确定它是否会返回正确的信息,因为它因此错误而失败:

{ "$match" : { "regionId" : 1234 } },
{ "$sort" : { "regionId" : 1 , "typeId" : 1 , "timestamp" : -1 } },
{ "$group" : {
    "_id" : { "regionId" : "$regionId" , "typeId" : "$typeId" },
    "timestamp" : { "$first" : "$timestamp" },
    "otherStuff" : { "$first" : "$otherStuff" },
} }

有关如何做到这一点的任何提示吗?

1 个答案:

答案 0 :(得分:0)

编写此查询的最有效方法是什么

您的查询不需要进行任何聚合(即计算值或处理文档),因此您应该使用带有限制的标准find()查询。

mongo shell中的示例:

db.foo.find({"regionId":1234}).sort({"regionId":1,"typeId":1,"timestamp":-1 }).limit(1)

符合您的查询和排序条件的合适索引将是:

db.foo.ensureIndex({"regionId":1, "typeId":1 , "timestamp": -1})

如果你在MongoDB 2.6中添加了这个索引和explain()查询,你会看到类似于的输出:

db.foo.find({"regionId":1234}).sort({ "regionId" : 1 ,"typeId" : 1 ,"timestamp" : -1 }).limit(1).explain()
{
  "cursor": "BtreeCursor regionId_1_typeId_1_timestamp_-1",
  "isMultiKey": false,
  "n": 1,
  "nscannedObjects": 1,
  "nscanned": 1,
  "scanAndOrder": false,
  ...
}

上面的explain output表示这是一个理想的效率查询:

  • 使用了预期的索引(cursor值)
  • 必须扫描1个索引条目(nscanned值)才能返回1个结果(n值)
  • 索引中的文档顺序已经满足排序顺序(scanAndOrder值)

为什么我们聚合命令失败?

  

排序超出内存限制104857600字节,但未选择外部排序。

您遇到的异常是因为您的聚合管道没有合适的索引可供使用,而是在进行内存中排序。 MongoDB 2.6有一个100MB memory limit用于内存排序。

如果您希望聚合管道对大型数据集使用外部排序,则有allowDiskUse选项,但在这种情况下,异常是提示您的管道处理的数据远远多于单一结果。

相关问题