У меня есть коллекция категорий, и каждая категория имеет свой массив _id из другой коллекции.
Моя цель - создать бесконечную прокрутку, предоставляя N записей каждый раз, но с конца (последняя запись всегда самая последняя).
Категория
{
"_id" : ObjectId("625167ce3859b8465ccf69dc"),
"name" : {
"en" : "Category #1"
},
"tracks" : [
ObjectId("627f8475c229513838eed070"),
ObjectId("627f84b4c229513838eed074"),
ObjectId("6280ef548b97521c1f462266"),
ObjectId("6280ef68d147e83534f4ca03"),
ObjectId("6280ef6ad147e83534f4ca07"),
ObjectId("6280ef6bd147e83534f4ca0b"),
// and so on..
]
}
Код:
categories
.aggregate([
{
$match: {
_id: ObjectId(categoryId),
},
},
{
$project: {
tracks: {
$slice: ["$tracks", -N],
},
},
},
{
$lookup: {
from: "tracks",
as: "tracks",
localField: "tracks",
foreignField: "_id",
pipeline: [{ $sort: { uploadedDate: -1 } }],
},
},
])
Итак, в основном я нарезаю массив, чтобы получить последние N элементов, а затем просматриваю их в коллекции tracks. Но я хочу получить N записей с конца между определенным диапазоном.
Например, если у меня есть 100 записей, поэтому я задаю номер итерации 0 и объемный размер: 25, будут возвращены последние 25 элементов (индекс 75-99).
На итерации 1 будут возвращены следующие (в обратном направлении) 25 элементов (индекс 50-74) и так далее...
На самом деле вы можете использовать $slice с позиции: видеть это
@nimrodserok это то, что я пробовал, но я не могу использовать отрицательное число, если добавлю position. дело в том, что мне нужно N записей с конца (последний элемент всегда самый последний), поэтому мне нужно 25 записей из последнего индекса - 25 и т. д. Я могу нарезать до -N, но это всегда даст 25, 50 , 75 последних записей (придется загружать одни и те же элементы + 25 новых), а не 25 записей каждый раз между определенным диапазоном
Я не понимаю, что ты говоришь. Если у вас есть список из 100 документов, вы можете получить последний диапазон X ИЛИ (от индекса a до индекса c), по логике вещей, таких вещей нет, оба из них... Вы хотите, чтобы запрос дал вам один из эти параметры в соответствии с его вводом?
@nimrodserok скажем, у меня есть 10 тысяч документов, я хочу каждый раз получать 25 документов. документ 10K самый последний, поэтому мне нужно получить документы с конца.. 10 000 до 9 975, а затем 9 975 до 9 950 и так далее. дело в том, что мне нужно получить N элементов между определенным диапазоном, но с конца коллекции, если есть способ сделать это, надеюсь, это понятно.

Вы можете так что-то вроде:
Обновлено: для поддержки крайних случаев:
db.collection.aggregate([
{
$match: {_id: ObjectId("625167ce3859b8465ccf69dc")}
},
{
$addFields: {
avilableCount: {$max: [
{$subtract: [{$size: "$tracks" }, bulkSize * iterations]},
0]}
}
},
{
$project: {
tracks: {
$cond: [{$eq: ["$avilableCount", 0]},
[],
{$slice: ["$tracks", {
$max: [
{$subtract: [{$size: "$tracks"}, bulkSize * (iterations + 1)]}, 0]},
{$min: [bulkSize , "$avilableCount"]}
]
}
]
}
}
}
])
Это вернет вам большую часть дорожек с размером bulkSize, начиная с конца списка для первой итерации и идя назад по итерациям. Итак, если у вас есть 100 дорожек с индексом 0-99 и bulkSize равно 25, вы получите дорожки 75-99 для первой итерации, 50-74 для 2-й итерации и 25-49 для 3-й...
avilableCount позволяет нам взглянуть на крайние случаи:
В крайнем случае, когда доступна только часть объема, он вернет эту часть, а если он недоступен, он вернет [].
Это то, что я хотел, но в случае, если у меня 85 страниц, bulkSize равен 25, а итерация - 3, он должен возвращать индексы 0-9, а не 71-85. А также есть ли способ использовать условия? если bulkSize * (итерации + 1) > track.length, чтобы не возвращать элементы по умолчанию? (Мне нужно знать, когда это закончится, поэтому я перестану прокручивать пользователя)
Обновил вопрос в соответствии с комментарием
Я думаю, это именно то, чего я пытался добиться, работая так, как ожидалось. спасибо, ачи, я ценю!
@nimrodserok можешь показать пример? если я добавлю
skip, это применит категории, но не треки. Также я хочу, чтобы это было эффективно, чтобы сделать это до поиска, чтобы он работал быстрее.