我正在使用 MongoDB 2.6.3 来查询大量地理空间数据。具体来说,我正在查询数据集以获取中心位置几公里范围内的所有 ping,然后按用户标识符折叠它们,以获取每个用户拥有多少 ping 的计数。
当然,我为此使用 MongoDB 聚合,特别是 $geoNear 管道阶段。然而,看起来,即使聚合在 2.6.0 中返回游标,$geoNear 仍然对聚合返回文档时绑定的结果集的大小有限制。也就是说,使用 $geoNear 进行聚合仅返回 65,000 条记录,而等效(光标)查询则返回 200,000 多条记录。
有人知道如何使用 geoNear 执行大规模聚合吗?
编辑: 样本文件:
{
"initial_epoch_time" : 1370062800,
"location" : [
-72.3458073902,
41.8241332683
],
"_id" : ObjectId("540a34050dc2520000912286"),
"__v" : 0
}
以下游标查询返回约 200,000 个文档的计数,我怀疑这是正确的数字:
var cursor = db.pings.find( { location : { $near: { $geometry: { type: 'Point', coordinates: [-71.10560939999999, 42.3465666] }, $maxDistance: 10*1000 } } } )
var ctr = 0;
while(cursor.hasNext())
{ ctr++;
var ping = cursor.next()
}
print(ctr)
而以下基于聚合的查询:
var cursor = db.pings.aggregate ( [ {$geoNear: { near: {type: "Point", coordinates: [-71.10560939999999, 42.3465666]},limit: 100000000, spherical: true, maxDistance: 10*1000, distanceField: "distance"} } ] )
var ctr = 0;
while(cursor.hasNext())
{ ctr++;
var ping = cursor.next()
}
print(ctr)
返回约 65,000 个文档,无论 maxDistance 是多少。
$geoNear 作为命令,输出的文档限制为 16MB。我发现您不会检索到任何错误,但文档将自动剪切到聚合的文档大小限制。您可以通过减小集合中文档的大小来进行测试。当您缩小集合文档时,您将获得更多结果。
第235行: https://github.com/mongodb/mongo/blob/master/src/mongo/db/commands/geo_near_cmd.cpp
新的命令文件似乎不再有这个
BSONObjMaxUserSize
限制了。这似乎在 MongoDB 4.2 中已被“修复”。如果使用旧版本,上一个链接还提供了一些潜在解决方法的建议:
使用 find 命令可用的 geoNear 运算符。如果需要对数据进行任何后续转换,则:
- 将查找操作的输出保留到一个集合,该集合可以对其运行后续聚合以生成最终结果,或者
如果结果不需要按距离排序,那么 $geoWithin 可能是一个合适的替代方案。
- 在客户端执行剩余的计算。