Nick
а мож туплю уже, но тогда чем помешала первая ссылка в гугле?
db.coll.find().sort( {"a":1} ).skip(count / 2 - 1).limit(1);
yopp
Alexander
yopp
вы это внутри map/reduce делаете? не так много мест в монге где можно js использовать
Al
const FolderSchema = new mongoose.Schema(
{
name: { type: String, required: true },
isFile: { type: Boolean, required: true },
isRoot: { type: Boolean, default: false },
//trashedAt: { type: Date, index: true },
deletedAt: { type: Date, index: true },
parent: {
type: mongoose.Schema.Types.ObjectId,
index: true,
ref: "Folder"
},
user: {
type: mongoose.Schema.Types.ObjectId,
index: true,
ref: "User",
required: true
}
},
{
versionKey: false
}
)
const folderWithParents = await Folder.aggregate([
{ $match: { _id: folder._id } },
{
$graphLookup: {
from: "Folder",
startWith: "$parent",
connectFromField: "parent",
connectToField: "_id",
as: "ancestors",
depthField: "depth"
//restrictSearchWithMatch: { parent: { $ne: null } }
}
}
]).exec()
console.log("path", folderWithParents)
Продолжаю с graphLookup
FolderSchema.statics.getAncestors = async function(folderId) {
const folderWithAncestors = await this.aggregate([
{ $match: { _id: folderId } },
{
$graphLookup: {
from: "folders",
startWith: "$parent",
connectFromField: "parent",
connectToField: "_id",
as: "ancestors",
depthField: "depth"
//restrictSearchWithMatch: { parent: { $ne: null } }
}
}
]).exec()
return folderWithAncestors
}
А как сортировать потомков по depth?
а то они не упорядоченны..
Al
Al
Пробую так:
const folderWithAncestors = await this.aggregate([
{ $match: { _id: folderId } },
{
$graphLookup: {
from: "folders",
startWith: "$parent",
connectFromField: "parent",
connectToField: "_id",
as: "ancestors",
depthField: "depth"
//restrictSearchWithMatch: { parent: { $ne: null } }
}
},
{
$sort: { "ancestors.depth": 1 }
}
]).exec()
Al
все тоже самое..
Nick
$sort не сортирует внутри массивов
Al
const folderWithAncestors = await this.aggregate([
{ $match: { _id: folderId } },
{
$graphLookup: {
from: "folders",
startWith: "$parent",
connectFromField: "parent",
connectToField: "_id",
as: "ancestors",
depthField: "depth"
//restrictSearchWithMatch: { parent: { $ne: null } }
}
},
{ $unwind: "$ancestors" },
{
$sort: { "ancestors.depth": -1 }
}
]).exec()
Al
вот так отсортировал..
Al
Nick
ну так он вам отсортировал доки верхнего уровня
Al
теперь надо как то верно отдать результат ... убрать из каждого элемента данные кроме ancestors ...
Nick
они не в массивах а просто вложенные
Nick
я выше говорил именно про массивы
Al
после unwind не в массиве..
Al
выше то понятно..
Al
теперь нужен видимо project...
yopp
сортируйте на клиенте
Al
const folderWithAncestors = await this.aggregate([
{ $match: { _id: folderId } },
{
$graphLookup: {
from: "folders",
startWith: "$parent",
connectFromField: "parent",
connectToField: "_id",
as: "ancestors",
depthField: "depth"
//restrictSearchWithMatch: { parent: { $ne: null } }
}
},
{ $unwind: "$ancestors" },
{
$sort: { "ancestors.depth": -1 }
},
{ $group: { _id: "$_id", ancestors: { $push: "$ancestors" } } },
{ $project: { _id: 0, ancestors: 1 } }
]).exec()
Al
да вот уже кое что получилось
Al
Al
как вынести ancestors из ancestors ?
Nick
я бы на порядок в $push не расчитывал
Al
а почему?
Nick
найдете в описании $pusр чтото про порядок - скиньте сюда
Al
по сути после sort у меня есть то что нужно... а как бы отсечь лишнее после sort ?
Al
const folderWithAncestors = await this.aggregate([
{ $match: { _id: folderId } },
{
$graphLookup: {
from: "folders",
startWith: "$parent",
connectFromField: "parent",
connectToField: "_id",
as: "ancestors",
depthField: "depth"
//restrictSearchWithMatch: { parent: { $ne: null } }
}
},
{ $unwind: "$ancestors" },
{
$sort: { "ancestors.depth": -1 }
// },
// { $group: { _id: "$_id", ancestors: { $push: "$ancestors" } } },
// { $project: { _id: 0, ancestors: 1 }
}
]).exec()
Al
ну а если тут сделать project ?
Al
будет более верно?
Nick
скажите для начала что вам нужно получить
Al
да просто список потомков
Nick
э не
Al
в структуре дерева связанного через parent
Nick
вы тут сортирвоки придумываете всякие
Nick
это уже не просто список
Al
но список должен быть сортирован по глубине... от самого глубокого к рутовому..
Al
а как иначе?
Nick
о
Al
Al
конечно можно включить и затем игнорить. но аккуратнее не включать
Al
ну и для каждого потомка можно включать в ответ ишь следующие данные _id, name, depth (хотя опять же лишние поля можно игнорить...)
Al
можно ли это решить graphLookUp ?
Al
точно вариант с push не катит?
Nick
на какую глубину потомки нужны?
Al
вот что нашел:
$push - adds items in the order in which they were received. Also you can add same items several times
$addToSet - adds just unique items, but order of items is not guarantied
Al
на произвольную..
Al
но на практике может и сделаем ограничение.. но работать пусть долго должно с произвольной глубиной
Al
на самом деле такого не будет.. кому надо в нашем сайтике добавлять 10-ки вложенных папок... ну а если такое будет сделаем ограничением при добавлении разумное..
Al
также я учитываю что когда то, этот массив потомков будет использоватся не только для хлебных крошек. а и для проверка красивых url типа /folder1/folder2/folder3
Al
Пока же хотелось бы что бы при загрузке страницы с папкой, с вложенностью с глубиной всего в несколько папок.. вывелись хлебные крошки без тормозов.. а залипаний в цикле возможных..
Al
те меня вполне устраивает вариант с group и push если иначе трансформировать эти результы сложно..
Nick
тогда вам всеравно нужно останавливаться на шаге перед анвинд и сортировать на клиенте
Al
Al
на клиенте те в node js а никуда там через rest API в vue зашлю..
Nick
потому что раз вы не можете полагаться на порядок в пуше, то всеравно будете сортирвоать
Nick
либо можно забить и надеятсья что все будет ок
Al
почему не могу если push как указано выше добавляет в порядке получения
Al
ну как собственно просто в js arr.push кто ж его потом сортирует если там то что надо
Nick
порядок получения не равно порядок сортировки в предущем этапе
Nick
на основе каких спекуляций монга рзгоняет группировку мне неизвестно
Al
Nick
вы просто ен видите разницу между
порядок не сохраняется
и
порядок не гарантируется
Nick
вы говорите про 3-4к
Nick
набейте 1кк данных тестовых, погоняйте на выборках в 5к
Al
я говорил о максимум десятках папок
Nick
если все будет ок - значит можно говорить о том что все ок в вашем случае
Al
а 1000 папок даже на экране не поместится..
Nick
и опять же после обновы монги все это может разъехаться
Aga
в продакшне обновлялся кто?)
yopp
зачем это всё в монге делать
Al
Хорошо. Допустим я отсекаю то что после unwind
yopp
сортируйте на клиенте как вам надо
Al
как тогда до unwind отсечь более менее лишнее..