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