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 ] }
      }
   }
])