Mongodb: сортировка документов по массивам
Я хотел бы вернуть документы в порядке, упорядоченном по которому выполняется самое низкое значение foo.bar
(которое является объектами массива).
Я могу сделать db.collection.find().sort({foo.0.bar: 1})
, но это соответствует только первому элементу массива - и, как вы можете видеть в приведенном ниже примере, сначала будет сортировать элемент 1 (foo.0.bar = 5), если я ищу return item 2 first (foo.2.bar = 4)
, поскольку он имеет объект с наименьшим значением.
{
"name": "Item 1",
"foo": [
{
"bar": 5
},
{
"bar": 6
},
{
"bar": 7
}
]
}
{
"name": "item 2",
"foo": [
{
"bar": 6
},
{
"bar": 5
},
{
"bar": 4
}
]
}
Ответы
Ответ 1
Кажется, монго может это сделать.
Например, если у меня есть следующие документы:
{ a:{ b:[ {c:1}, {c:5 } ] } }
{ a:{ b:[ {c:0}, {c:12} ] } }
{ a:{ b:[ {c:4}, {c:3 } ] } }
{ a:{ b:[ {c:1}, {c:9 } ] } }
И запустите следующее:
db.collection.find({}).sort({ "a.b.c":1 });
// produces:
{ a:{ b:[ {c:0}, {c:12} ] } }
{ a:{ b:[ {c:1}, {c:5 } ] } }
{ a:{ b:[ {c:1}, {c:9 } ] } }
{ a:{ b:[ {c:4}, {c:3 } ] } }
db.collection.find({}).sort({ "a.b.c":-1 });
// produces:
{ a:{ b:[ {c:0}, {c:12} ] } }
{ a:{ b:[ {c:1}, {c:9 } ] } }
{ a:{ b:[ {c:1}, {c:5 } ] } }
{ a:{ b:[ {c:4}, {c:3 } ] } }
Как вы можете видеть, сортировка {"a.b.c":1}
принимает min всех значений в массиве и сортирует по ней, тогда как сортировка по {"a.b.c":-1}
занимает max всех значений.
Ответ 2
Альтернативой использованию map/reduce является сохранение значения min из массива в виде отдельного поля в документе, который вы могли бы затем заказать. Когда вы добавляете в массив, вы также обновляете это поле, если новое значение меньше, чем текущий записанный минимум.
например. ваш первый документ станет таким (примечание "добавлено minbar" ):
{
"name": "Item 1",
"minbar" : 5,
"foo": [
{
"bar": 5,
}
{
"bar": 6,
}
{
"bar": 7,
}
]
}
Ответ 3
Вы можете сделать такой вид с помощью агрегатной команды из версии mongo 2.2:
db.collection.aggregate([{$unwind: "$foo"},
{$project: {bars:"$foo.bar"}},
{$group: {_id:"$_id",min:{$min: "$bars"}}},
{$sort: {min:1}}])
Ответ 4
Нет прямого способа сделать это в монго. Вам нужно будет использовать map/reduce для извлечения min val в каждом массиве, а затем сортировать по этому минимальному значению