嘿,我有一个MongoDB数据库,并且我在Mongoose中使用Node.js。
我有一个猫鼬模式看起来像这样的集合:
{
location2d: {
type: [Number], //[<longitude>, <latitude>]
index: '2dsphere'
},
name: String,
owner: {type: Schema.Types.ObjectId, ref: 'Player', index: true},
}
这个馆藏很大(500'000个文档)。当我执行一个简单的最近查找查询时,它的运行速度非常快〜10 ms。
但是当我做这样的事情时:
this.find({owner: {$ne:null}})
.where('location2d')
.near({center: [center.lon, center.lat], maxDistance: range / 6380000, spherical: true})
.limit(10)
.select('owner location2d')
.exec()
这需要很长时间,大约需要60秒!只是因为我在
{owner: {$ne:null}}
方法中添加了find
,所以执行所需的时间乘以6000。我究竟做错了什么?我该如何改善?
当我按所有者进行搜索时,速度很快,当我按邻近程度进行搜索时,速度很快,但是当我将两者结合在一起时,它的速度却难以置信。
有什么线索吗?
最佳答案
好的,我找到了一个解决方案,虽然有点脏,但速度很快。
第一个:创建一个名为ownerIdAsInt
的新字段,该字段是所有者mongo Id:document.ownerIdAsInt = parseInt(document.owner.toString(), 16)
解析的int。如果owner
为null,则将该字段设置为0
第二:使用{ownerIdAsInt: 1, location2d: "2dsphere"}
定义复合索引
您的架构应如下所示:
var schema = new Schema({
location2d: {
type: [Number], //[<longitude>, <latitude>]
index: '2dsphere'
},
name: String,
owner: {type: Schema.Types.ObjectId, ref: 'Player', index: true},
ownerIdAsInt: Number
});
schema.index({ownerIdAsInt: 1, location2d: "2dsphere"});
现在查询是:
this.find({ownerIdAsInt: {$gt: 0},
location2d: {$nearSphere: [center.lon, center.lat],
$maxDistance: range / 6380000}})
.limit(10)
.select('owner location2d')
.exec()
现在的结果是〜20 ms长。快多了!