我在MongoDB集合上使用以下查询,这需要一个多小时才能完成。
db.collection.find({language:"hi"}).sort({_id:-1}).skip(5000).limit(1)
我试图以5000的批次结果获得结果以升序或降序处理文件" hi"作为语言领域的价值。所以我使用这个查询,我每次都通过递增"跳过"来跳过处理过的文档。值。
此系列中的文件数量刚刚超过2000万。 该字段的索引"语言"已经创建了。 我正在使用的MongoDB版本是2.6.7
此查询是否有更合适的索引可以更快地获得结果?
答案 0 :(得分:3)
如果要对降序进行排序,则应创建一个多字段索引,该索引使用您排序的字段作为降序字段。您可以将这些字段设置为-1
。
此索引应该会大大提高您的排序性能:
db.collection.ensureIndex({ language: 1, _id: -1 });
如果您还想加快其他情况 - 检索按升序排序 - 创建第二个索引,如下所示:
db.collection.ensureIndex({ language: 1, _id: 1 });
请记住,当您不对结果进行排序时,您会按自然顺序接收它们。自然顺序通常是 插入顺序,但不能保证。有各种事件可能导致自然顺序混乱,因此当您关心订单时,您应该始终明确排序。此规则的唯一例外是capped collections,它始终保持插入顺序。
答案 1 :(得分:0)
为了以您想要的方式有效地“浏览”结果,最好使用“范围查询”并保留您处理的最后一个值。
你想要的“排序键”这里是_id
,这样可以简化:
首先,您希望索引的顺序正确,而.createIndex()
不是弃用的方法:
db.collection.createIndex({ "language": 1, "_id": -1 })
然后你想从头开始做一些简单的处理:
var lastId = null;
var cursor = db.collection.find({language:"hi"});
cursor.sort({_id:-1}).limit(5000).forEach(funtion(doc) {
// do something with your document. But always set the next line
lastId = doc._id;
})
这是第一批。现在,当你继续下一个:
var cursor = db.collection.find({ "language":"hi", "_id": { "$lt": lastId });
cursor.sort({_id:-1}).limit(5000).forEach(funtion(doc) {
// do something with your document. But always set the next line
lastId = doc._id;
})
这样在进行选择时始终会考虑lastId
值。您可以在每个批次之间存储它,并从最后一个批次继续。
这比使用.skip()
处理效率要高得多,$lt
无论索引如何“仍然”需要“跳过”集合中的所有数据直到跳过点。
在此使用package business;
message Employee
{
required string first_name = 1;
required string last_name = 2;
required string email = 3;
}
message Company
{
required string name = 1;
optional string url = 2;
repeated Employee employee = 3;
}
运算符“过滤”您已处理的所有结果,以便您可以更快地移动。