#node.js #mongodb #mongoose
#node.js #MongoDB #мангуст
Вопрос:
надеюсь, у вас все хорошо, и всех с Новым годом. Надеюсь, что в конечном итоге это будет лучше, чем 2020 X). Здесь я столкнулся с проблемой, которую пока не могу найти решение. Вот пример модели данных MongoDB :
`{ "_id" : ObjectId("5fe715bf43c3ca0009503f1d"),
"firstname" : "Nicolas ",
"lastname" : "Mazzoleni",
"email" : "nicolas.mazzoleni@orange.fr",
"items" : [
{
"item" : ObjectId("5f6c5422eeaa1364b0d7b267"),
"createdAt" : "2020-12-26T10:51:43.685Z"
},
{
"item" : ObjectId("5f6c5422eeaa1364b0d7b270"),
"createdAt" : "2021-01-04T09:21:46.260Z"
}
],
"createdAt" : ISODate("2020-12-26T10:51:43.686Z"),
"updatedAt" : ISODate("2021-01-04T09:21:46.260Z"),
"__v" : 0
}`
Давайте предположим, что у меня много строк, подобных приведенной выше, с разными датами «items.createdAt».
В конце цель состоит в том, чтобы выполнить запрос, который найдет элемент, в котором идентификатор объекта равен тому, что я ищу, и отсортировать по соответствующей дате «items.createdAt». Вот запрос, который я использую в данный момент, который не сортирует по соответствующему вложенному объекту :
`const items = await repo
.find({ 'items.item': ObjectId("5f6c5422eeaa1364b0d7b270") })
.sort({ 'items.createdAt': -1 })
.limit(5)`
PS: я также пытался использовать агрегации, которые заканчивались этим запросом
`const items = await repo.aggregate([
{ $unwind: '$items' },
{ $match: { 'items.item': ObjectId("5f6c5422eeaa1364b0d7b270") } },
{ $sort: { 'items.createdAt': -1 } },
{ $limit: 5 },
])`
Этот работает как шарм, но он не использует индексы, и я просматриваю миллионы записей, что делает этот запрос слишком длинным для выполнения.
Спасибо за вашу помощь! Николас
Ответ №1:
К сожалению, MongoDB не может сортировать вложенный массив с помощью простого запроса. Для этого вам нужно использовать aggregate.
db.collection.aggregate([
{
"$match": {
"items.item": ObjectId("5f6c5422eeaa1364b0d7b270")
}
},
{
"$unwind": "$items"
},
{
"$sort": {
"items.createdAt": -1
}
},
{ "$limit" : 5 },
{
"$group": {
"items": {
"$push": "$items"
},
"_id": 1
}
])
Комментарии:
1. Эй, @JustRaman, спасибо за быстрый ответ. Итак, если aggregate является единственным решением, есть ли у вас способ сделать этот запрос с использованием индексов? Потому что база данных, лежащая в основе, содержит миллионы записей. Спасибо 🙏🏼
2. Aggregate будет использовать любые индексы, если не существует специального способа. кроме этого.