我有一个存储文章信息的集合。该集合用于存档目的,因此它是只读的。目前只使用了两个字段:“title”和“page_length”。因为我总是对首先获得更长的文章感兴趣,所以我有以下索引:{title:1,page_length:-1}。
我发现排序仍然很慢,因为集合非常大而且不适合内存。
假设我在这个集合上使用的几乎每个查询都需要排序({page_length:-1}),有没有办法简单地按照page_length的顺序将记录存储在磁盘上?换句话说,是否有一种简单的方法可以使集合中的第一条记录成为最大的page_length值,第二条记录是第二条记录,依此类推?
这样我就可以使用limit(n)获取前n个记录而无需运行排序。有什么想法吗?
使用更多信息进行更新:
我将其用于搜索自动完成功能,因此速度至关重要。我一直在使用的查询如下所示:
db.articles.find({"title": /^SomeKeyword/}).sort({page_length:-1})
我很高兴创建多个索引,因为插入不是问题,我只想最大化读取速度。
编辑:作为参考,我实际上能够通过将find()。forEach()用于新集合来重新组织集合中的记录。然后我搜索了该集合并抓住了前N个结果,而不需要任何排序,这非常有效。请注意,这只能起作用,因为我的数据集不会改变。
答案 0 :(得分:1)
您的索引{ title: 1, page_length: -1 }
不会用于如下所示的查询:
db.collection.find( {} ).sort( { page_length: -1 } );
MongoDB只能使用从左到右的复合索引,因此为了使用索引,你需要拥有" title"作为查找或排序参数:
db.collection.find({title:' foo'})。sort({page_length:-1}); db.collection.find()。sort({title:1,page_length:-1});
解释会告诉你:
db.so.find( {} ).sort( { page_length: -1 } ).explain();
{
"cursor" : "BasicCursor",
…
如果您将索引更改为:
db.so.ensureIndex({ page_length: -1, title: 1 } );
然后索引将用于排序,但您不能使用索引只是通过title
进行查找,您将需要一个额外的索引。如果您真的只对这两个字段感兴趣并确保使用覆盖索引有帮助。您必须使用{ page_length: -1, title: 1 }
获得复合索引,并且可以确保使用投影来使用它:
db.collection.find({},{page_length:1,title:1,_id:0})。sort({page_length:-1});
但是你不能决定或影响MongoDB如何在磁盘上存储东西。
答案 1 :(得分:0)
我可以想到一个使用两个查询的解决方案。
首先,您可以执行covered query来获取您关注的文档列表。其次,您可以使用检索到的文档列表和$in
运算符来获得最终结果。
覆盖的查询将在内存中运行(或者至少在磁盘上顺序运行),因此它应该很快,$in
可以使用_id
索引,并且应该具有合理的数量文件。