目前我们在MongoDB 3.2.9中的$near操作遇到了大麻烦.
问题是在创建游标时有无尽的负载 – 直到超时.这个问题只是在我们没有使用$maxDistance时 – 这在我们的情况下很重要,不能使用.
这是我们的收藏:
地点
带有GeoJSON属性“geometry”的大约2.000.000个文档,它也被索引.
除了几何之外,还有另一个名为“类别”的索引.
在我们的特殊情况下,我们的查询现在如下所示:
Locations.find({
category: 'ABC',
geometry: {
'$near': {
$geometry: {
type: "Point" ,
coordinates: [ 13.357315063476564, 52.53167855932515 ]
}
}
}
}, {
limit: 10
});
此查询将导致超时.
要解决这个问题,我们需要添加$maxDistance操作,它会正常工作(如果$maxDistance的值不是太高)但在我们的例子中,$maxDistance非常糟糕,因为如果1个位置有一个与另一个人的距离很远.例如,当第一个找到的位置在挪威,第二个位于澳大利亚的某个地方时,它没问题.
另一个信息:
这个问题只会导致LESS然后是结果的限制.在上面的示例中,我们的数据库中有8个具有此类别的位置.如果我们在10个以上的位置进行相同的查询,则需要大约几毫秒.
总结一下:
// Does not work. Ends up in an timeout
Locations.find({
category: 'ABC', // has 9 locations
geometry: {
'$near': {
$geometry: {
type: "Point" ,
coordinates: [ 13.357315063476564, 52.53167855932515 ]
}
}
}
}, {
limit: 10
});
// Works fine because of the $maxDistance - but in our case a $maxDistance is very BAD and needed to be prevented!
Locations.find({
category: 'ABC', // has 9 locations
geometry: {
'$near': {
$geometry: {
type: "Point" ,
coordinates: [ 13.357315063476564, 52.53167855932515 ]
}
},
'$maxDistance': 5000 // If this value is too high - like the maxDistance is "the whole world" the query would also end up in an timeout
}
}, {
limit: 10
});
// Works fine because >= 10 items
Locations.find({
category: 'DEF', // has 10 locations
geometry: {
'$near': {
$geometry: {
type: "Point" ,
coordinates: [ 13.357315063476564, 52.53167855932515 ]
}
}
}
}, {
limit: 10
});
我们正在使用MongoDB 3.2.9
附加信息
这个问题与我们在nodeJS中使用MongoDB的事实无关.我们也在使用RoboMongo,在执行此查询时,同样的问题会导致:超时!
最佳答案 我创建了一个集合,因为您包含200万个带有随机数据的文档,为类别和几何字段准备了索引.当我继续测试这个集合时,我遇到了和你一样的问题.
没有$maxDistance值花了大约50秒.起初它似乎是合理的,因为没有$maxDistance Mongo必须搜索“全世界”的结果.但后来我检查了查询的.explain()
结果并意识到它根本没有使用索引,在查询中没有阶段IXSCAN
(这是旧版Mongo中的BasicCursor).所以问题很明显,我错误地创建了索引,你也是.
你(我也是)创建的索引是Single Field Indexes,只有在按单个字段搜索时才有帮助.在这种情况下,您需要搜索两个字段,因此需要使用Compound Indexes.使用此命令创建可在搜索中使用的复合索引:
db.collection({category: 1, geometry: '2dsphere'});
我做到了,结果令人惊讶,时间从50秒减少到几百毫秒.