Получить первый элемент в массиве и вернуть с помощью Aggregate? (В MongoDB)
как я получаю первый элемент в массиве и возвращаю его в Mongo aggregate?
Я пытаюсь запустить этот код в mongo, но не удается:
db.my_collection.aggregate([
{ $project: {
resp : { my_field: { $slice: 1 } }
}}
])
OBS: 'my_field' - это массив с 4 позиции, мне нужно вернуть только первый элемент.
вернуться:
uncaught exception: aggregate failed: {
"errmsg" : "exception: invalid operator '$slice'",
"code" : 15999,
"ok" : 0
}
4 ответов
в настоящее время $slice
оператор недоступен в $project
операция конвейера агрегации.
Так что вы могли бы сделать,
первый $unwind
на my_field
массив, а затем сгруппировать их вместе и взять $first
элемент группы.
db.my_collection.aggregate([
{$unwind:"$my_field"},
{$group:{"_id":"$_id","resp":{$first:"$my_field"}}},
{$project:{"_id":0,"resp":1}}
])
или с помощью find()
команда, где вы можете использовать оператор $slice в projection
часть.
db.my_collection.find({},{"my_field":{$slice:1}})
обновление: основываясь на ваших комментариях, скажите, что вы хотите только second
элемент в массиве, для записи с идентификатором,id
.
var field = 2;
var id = ObjectId("...");
затем приведенная ниже команда агрегирования дает вам 2-й элемент в my_field
массив записи с _id
, id
.
db.my_collection.aggregate([
{$match:{"_id":id}},
{$unwind:"$my_field"},
{$skip:field-1},
{$limit:1}
])
приведенная выше логика не может быть применена для более записи, так как она будет включать $group
, оператор $unwind
. The $group
оператор создает одну запись для всех записей в этой конкретной группе делает $limit
или $skip
операторы, применяемые на более поздних этапах, неэффективны.
небольшая вариация на тему find()
запрос выше даст вам ожидаемый результат.
db.my_collection.find({},{"my_field":{$slice:[field-1,1]}})
помимо этого, всегда есть способ сделать это на стороне клиента, хотя немного дорого, если количество записей очень велико:
var field = 2;
db.my_collection.find().map(function(doc){
return doc.my_field[field-1];
})
выбор из вышеперечисленных вариантов зависит от вашего размера данных и дизайна приложения.
С 3.2, мы можем использовать $arrayElemAt
чтобы получить первый элемент в массиве
db.my_collection.aggregate([
{ $project: {
resp : { $arrayElemAt: ['$my_field',0] }
}}
])
оператор $slice планируется сделать доступным в операции $project в Mongo 3.1.4, согласно этому билету:https://jira.mongodb.org/browse/SERVER-6074
Это заставит проблему уйти.
эта версия в настоящее время только в релиз и еще не стабильный (по состоянию на июль 2015). Ожидайте этого примерно в октябре / ноябре.
Монго 3.1.6 года,
db.my_collection.aggregate([
{
"$project": {
"newArray" : { "$slice" : [ "$oldarray" , 0, 1 ] }
}
}
])
здесь 0
- начальный индекс и 1
- это количество элементов для среза