Получить первый элемент в массиве и вернуть с помощью 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 - это количество элементов для среза