【发布时间】:2012-10-27 20:23:32
【问题描述】:
假设我有一个文档集合,其中包含一个浮点数的 ratio 属性。
{'ratio':1.437}
如何编写查询以查找与给定整数值最接近的单个文档,而不使用驱动程序将它们全部加载到内存中并找到具有最小值 abs(x-ratio) 的文档?
【问题讨论】:
假设我有一个文档集合,其中包含一个浮点数的 ratio 属性。
{'ratio':1.437}
如何编写查询以查找与给定整数值最接近的单个文档,而不使用驱动程序将它们全部加载到内存中并找到具有最小值 abs(x-ratio) 的文档?
【问题讨论】:
有趣的问题。我不知道您是否可以在一个查询中完成,但您可以在两个查询中完成:
var x = 1; // given integer
closestBelow = db.test.find({ratio: {$lte: x}}).sort({ratio: -1}).limit(1);
closestAbove = db.test.find({ratio: {$gt: x}}).sort({ratio: 1}).limit(1);
然后您只需检查两个文档中的哪一个具有最接近目标整数的ratio。
MongoDB 3.2 更新
3.2 版本增加了对 $abs 绝对值聚合运算符的支持,现在允许在单个 aggregate 查询中完成此操作:
var x = 1;
db.test.aggregate([
// Project a diff field that's the absolute difference along with the original doc.
{$project: {diff: {$abs: {$subtract: [x, '$ratio']}}, doc: '$$ROOT'}},
// Order the docs by diff
{$sort: {diff: 1}},
// Take the first one
{$limit: 1}
])
【讨论】:
ratio 的索引?我怀疑对数据库有两个请求的第一个解决方案对于较大的集合可能会更快。
我有另一个想法,但很棘手,需要改变你的数据结构。
你可以使用mongodb支持的geolocation index
首先,将您的数据更改为这种结构,并将第二个值保留为 0
{'ratio':[1.437, 0]}
然后您可以使用$near 运算符找到最接近的比率值,并且由于该运算符返回一个按距离排序的列表以及您给出的整数,因此您必须使用limit 仅获取最接近的值。
db.places.find( { ratio : { $near : [50,0] } } ).limit(1)
如果您不想这样做,我认为您可以使用@JohnnyHK 的答案 :)
【讨论】: