目前我们在$near
中的MongoDB 3.2.9
操作遇到了大麻烦。
问题是在创建游标时有无尽的负载 - 直到超时。这个问题只会导致我们不使用$maxDistance
- 在我们的情况下,重要的是不要使用它。
这是我们的收藏:
地点
带有GeoJSON属性的大约2.000.000个文档" geometry"这也是索引。
除了几何外,还有另一个名为" category"。
的索引在我们的特殊情况下,我们的查询现在看起来像这样:
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,在执行此查询时,同样的问题会导致:超时!
答案 0 :(得分:1)
我创建了一个集合,因为您包含200万个包含随机数据的文档,为category
和geometry
字段准备了索引。当我继续测试这个集合时,我遇到了和你一样的问题。
没有$maxDistance
值花了大约50秒。起初它似乎是合理的,因为没有$maxDistance
Mongo必须搜索“全世界”的结果。但后来我检查了查询的.explain()
结果并意识到它根本没有使用索引,在查询中没有阶段IXSCAN
(在旧版本的Mongo中这是BasicCursor
) 。所以问题很明显,我错误地创建了索引,你也是。
您(我也是)创建的索引是Single Field Indexes,只有在按单个字段搜索时才有用。在这种情况下,您需要搜索两个字段,因此您需要使用Compound Indexes。使用此命令创建可在搜索中使用的复合索引:
db.collection({category: 1, geometry: '2dsphere'});
我做到了,效果惊人,时间从50秒减少到几百毫秒。