MongoDB-запрос на последний элемент массива?

Я знаю, что MongoDB поддерживает синтаксис find{array.0.field:"value"}, но я специально хочу сделать это для последнего элемента в массиве, который означает, что я не знаю индекса. Есть ли какой-то оператор для этого, или мне повезло?

EDIT: чтобы уточнить, я хочу, чтобы find() возвращал только документы, где поле в последнем элементе массива соответствует определенному значению.

7 ответов


в 3.2 это возможно. Сначала проект, чтобы myField содержал только последний элемент, а затем совпадение на myField.

db.collection.aggregate([
   { $project: { id: 1, myField: { $slice: [ "$myField", -1 ] } } },
   { $match: { myField: "myValue" } }
]);

Я опубликовал на официальном Mongo Google group здесь, и получил ответ от своих сотрудников. Похоже, то, что я ищу, невозможно. Я собираюсь просто использовать другой подход схемы.


использовать $slice.

db.collection.find( {}, { array_field: { $slice: -1 } } )

редактирование: Вы можете использовать { <field>: { $elemMatch: { <query1>, <query2>, ... } } } найти матч.

но это не даст именно то, что вы ищете. Я не думаю, что это возможно в MongoDB еще.


Не уверен в производительности, но это хорошо работает для меня:

db.getCollection('test').find(
  {
    $where: "this.someArray[this.someArray.length - 1] === 'pattern'"
  }
)

можно использовать $position: 0 всякий раз, когда вы $push, а затем всегда запрашивать array.0 чтобы получить последний добавленный элемент. Конечно, тогда вы не сможете получить новый" последний " элемент.


можно использовать $expr ( оператор версии 3.6 mongo) для использования функций агрегации в регулярном запросе.

сравнить query operators vs aggregation comparison operators.

для скалярных массивов

db.col.find({$expr:{$gt:[{$arrayElemAt:["array", -1]}, value]}})

для встроенных массивов - использовать $arrayElemAt выражение с точечной нотацией для проецирования последнего элемента.

db.col.find({$expr:{$gt:[{"$arrayElemAt": ["$array.field", 0]}, value]}})

Весна @Query код

@Query("{$expr:{$gt:[{$arrayElemAt:[\"array\", -1]}, ?0]}}")
ReturnType MethodName(ArgType arg);

версия 3.6 используйте агрегацию для достижения того же.

db.getCollection('deviceTrackerHistory').aggregate([
   {
     $match:{clientId:"12"}
   },
   {
     $project:
      {
         deviceId:1,
         recent: { $arrayElemAt: [ "$history", -1 ] }
      }
   }
])