嘿,我有一个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长。快多了!

08-28 15:12