Ответ 1
Я разместил в официальной группе Mongo Google здесь и получил ответ от своего персонала. Похоже, что то, что я ищу, невозможно. Я просто использую другой подход к схеме.
Я знаю, что MongoDB поддерживает синтаксис find{array.0.field:"value"}
, но я специально хочу сделать это для последнего элемента в массиве, а это значит, что я не знаю индекса. Для этого есть какой-то оператор, или мне не повезло?
EDIT: Чтобы уточнить, я хочу, чтобы find() возвращал только те документы, где поле в последнем элементе массива соответствует определенному значению.
Я разместил в официальной группе Mongo Google здесь и получил ответ от своего персонала. Похоже, что то, что я ищу, невозможно. Я просто использую другой подход к схеме.
В 3.2 это возможно. Первый проект, так что myField содержит только последний элемент, а затем соответствует myField.
db.collection.aggregate([
{ $project: { id: 1, myField: { $slice: [ "$myField", -1 ] } } },
{ $match: { myField: "myValue" } }
]);
используйте $slice.
db.collection.find( {}, { array_field: { $slice: -1 } } )
Редактирование:
Вы можете использовать
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
, чтобы найти совпадение.
Но это не даст точно то, что вы ищете. Я не думаю, что это возможно в mongoDB еще.
Вы можете использовать $ expr (оператор версии 3.6 mongo), чтобы использовать функции агрегирования в обычном запросе.
Сравните query operators
с aggregation comparison operators
.
Для скалярных массивов
db.col.find({$expr: {$gt: [{$arrayElemAt: ["array", -1]}, value]}})
Для встроенных массивов - используйте выражение $arrayElemAt
с точечной нотацией для проецирования последнего элемента.
db.col.find({$expr: {$gt: [{"$arrayElemAt": ["$array.field", -1]}, value]}})
Spring @Query
код
@Query("{$expr:{$gt:[{$arrayElemAt:[\"array\", -1]}, ?0]}}")
ReturnType MethodName(ArgType arg);
Не уверен в производительности, но это хорошо работает для меня:
db.getCollection('test').find(
{
$where: "this.someArray[this.someArray.length - 1] === 'pattern'"
}
)
Вы можете использовать $position: 0
всякий раз, когда вы $push
, а затем всегда запрашивать array.0
чтобы получить последний добавленный элемент. Конечно, тогда вы не сможете получить новый "последний" элемент.
Версия 3.6 используйте агрегацию для достижения того же.
db.getCollection('deviceTrackerHistory').aggregate([
{
$match:{clientId:"12"}
},
{
$project:
{
deviceId:1,
recent: { $arrayElemAt: [ "$history", -1 ] }
}
}
])
Может кто-нибудь дать выше запрос в формате шаблона монго. Как при использовании Aggregation aggregation = newAggregation (фильтры)