Mongodb - Найти документ с ближайшим целочисленным значением
Предположим, что у меня есть коллекция с документами с атрибутом отношения, который является числом с плавающей запятой.
{'ratio':1.437}
Как написать запрос, чтобы найти одиночный документ с ближайшим значением к заданному целому числу, не загружая их все в память с помощью драйвера и находя его с наименьшим значением abs(x-ratio)
?
Ответы
Ответ 1
Интересная проблема. Я не знаю, можете ли вы сделать это в одном запросе, но вы можете сделать это двумя:
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 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}
])
Ответ 2
У меня есть другая идея, но очень сложная задача и нужно изменить структуру данных.
Вы можете использовать индекс геолокации, который поддерживается mongodb
Сначала измените свои данные на эту структуру и сохраните второе значение с помощью 0
{'ratio':[1.437, 0]}
Затем вы можете использовать оператор $near
, чтобы найти ближайшее значение отношения, и потому что оператор возвращает список, отсортированный по расстоянию, с заданным вами целым числом, вы должны использовать limit
, чтобы получить только самое близкое значение.
db.places.find( { ratio : { $near : [50,0] } } ).limit(1)
Если вы не хотите этого делать, я думаю, вы можете просто использовать @JohnnyHK ответ:)