使用MongoDB v2.6,如果从大型结果集中对cursor进行排序以获得overflow,则情况并不鲜见。
cursor = db.collection.find( { "key" : "value" } )
cursor.sort( { "rank" : 1 } ) // This can blow up
错误看起来很像:
运行程序错误:溢出排序阶段缓冲数据使用量33598393字节超出内部限制33554432字节
在这种情况下,解决方案的解决方案是provide an index,而不仅仅是密钥。
db.collection.ensureIndex( { "rank" : 1 } ) // ascending
这很好用。
我在另一个地方遇到此问题,text index。按照text index creation上的MongoDB手册中的说明,我已经正是这样做了:
db.collection.ensureIndex(
{ "$**": "text" },
{ name: "TextIndex" }
)
并且,这已经在集合中所有ExtendedJSON个对象的所有字段中创建了一个文本索引。
搜索效果很好。
cursor = db.collection.find( { "$text" : { "$search" : "NEEDLE" } } )
cursor.count() // w00t! records that have NEEDLE in them
但是,尝试执行之前工作的相同排序,即使存在排序字段的索引:
db.collection.ensureIndex( { "rank" : 1 } )
cursor = db.collection.find( { "$text" : { "$search" : "NEEDLE" } } )
cursor.sort( { "rank" : 1 } ) // This blows up with the same error message
运行程序错误:溢出排序阶段缓冲数据使用量33598393字节超出内部限制33554432字节
这是奇怪的部分。
迭代光标而不用执行排序工作正常,这就是我如何计算上面的数字。我甚至可以单步浏览光标并查看无序结果,因此文本搜索显然可以正常工作。
但是,省略文本搜索会导致排序正常工作;这让我觉得它不是基于数量的,虽然我知道它实际上只是使用了排序键的索引。
db.collection.ensureIndex( { "rank" : 1 } )
cursor = db.collection.find( ) // Get absolutely everything
cursor.sort( { "rank" : 1 } ) // Well, sort now works again... hmm....
正如我必须"帮助" Mongo提供了一个索引,因此可以在不将所有记录带入内存的情况下进行排序,如何为文本索引实现此目的呢?
不幸的是,我无法获得explain plan,因为它也会产生同样的错误。如果我对.find() sans .sort()的结果执行此操作,则会显示明显的 - 对数据的完整扫描,没有IndexBounds
字段。
ADDENDUM:它不是一个字段,而是所有字段,我试图将文本编入索引 - 因此"$**"
。作为一个实验,我在所有字段上手动执行了.ensureIndex(...)
,希望这有助于排序。但请记住,我并没有尝试对文本字段进行排序 - 仅仅将其用作获取与搜索条件匹配的JSON对象集合的机制。一旦我拥有了该集合,并且我确实获得了该集合,我就会尝试按rank
字段对其进行排序,该字段已经有索引并且可以在其他方案中使用。
答案 0 :(得分:0)
也许这link会对你有帮助。
总结一下:你不应该在程序中间调用ensureIndex,而是让Mongoose为你调用它。只需将Schema中的标记index: true
添加到要用于排序的字段即可。在你的情况下,将它添加到排名和名称应该没问题。至少这在我的项目中对我有用。
示例:
var schema = mongoose.Schema({
...
normalText : String,
rank : { type: Number, index: true},
name : { type: String, index: true }
});
答案 1 :(得分:0)
希望这可以提供帮助。 尝试添加这样的代码。 这是为了排序排名。 $ cursor = $ cursor.sort({" rank":1})); 但你需要对$ text进行排序, 试试这个, $ cursor = $ cursor-> sort({" text":1});
感谢。