MongoDB Как сортировать в обе стороны от числа?
Допустим, в коллекции есть такие документы:
{name: "Test 1", value: "1"}
{name: "Test 2", value: "2"}
{name: "Test 3", value: "3"}
{name: "Test 4", value: "4"}
{name: "Test 5", value: "5"}
{name: "Test 6", value: "6"}
Выбираем медиану значений value ([1,2,3,4,5,6]) - 3.5 Нужно отсортировать документы, чтобы значения шли от медианы (3.5) в обе стороны:
{name: "Test 3", value: "3"}
{name: "Test 4", value: "4"}
{name: "Test 2", value: "2"}
{name: "Test 5", value: "5"}
{name: "Test 1", value: "1"}
{name: "Test 6", value: "6"}
Ответы (1 шт):
Значение value: "1" не подходит для математических операций, нужно исправить тип со строки на число.
Я буду исходить из того, что данные вставлены по принципу db.data.insert({name: "Test 1", value: 1});.
Итак, нужно сделать вычисляемое поле, по которому отсортировать. Для этого нужно вычесть из value 3.5 и получить абсолютное значение. То есть abs(value - 3.5).
Для этого нужно использовать aggregate, в котором добавить project, где с помощью функций вычислить значение:
db.data.aggregate([
{
$project: {
"_id": 0,
"name": 1,
"value": 1,
"orderBy": {
$abs: {
$add: ["$value", -3.5]
}
}
}
},
{"$sort": {"orderBy": 1}}
]);
Результат:
{ "name" : "Test 3", "value" : 3, "orderBy" : 0.5 }
{ "name" : "Test 4", "value" : 4, "orderBy" : 0.5 }
{ "name" : "Test 2", "value" : 2, "orderBy" : 1.5 }
{ "name" : "Test 5", "value" : 5, "orderBy" : 1.5 }
{ "name" : "Test 1", "value" : 1, "orderBy" : 2.5 }
{ "name" : "Test 6", "value" : 6, "orderBy" : 2.5 }
Еще раз повторю, что value должно быть числом, а не строкой, иначе будет ошибка. Либо нужно сделать преобразование типов через $toInt, но эта операция доступна в Mongo 4+, и я не могу проверить. Но должно быть так:
"orderBy": {
$abs: {
$add: [
{$toInt: "$value"}, -3.5
]
}
}