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