Al
Появилось поле shared в результах в котором результат left join ... а как сделать что то типа подсчитать сколько таких shared ?
Igor
Al
this.aggregate([
{ $match: { parent: ObjectId(folderId), deletedAt: null } },
{
$facet: {
folders: [
{
$match: {
isFile: false
}
},
{
$sort: sortCondition
},
{
$lookup: {
from: "folders",
localField: "_id",
foreignField: "linkedTo",
as: "shared"
}
}
],
files: [
{
$match: {
isFile: true
}
},
{
$sort: sortCondition
}
]
}
},
{
$project: { folders: { $concatArrays: foldersUp ? ["$folders", "$files"] : ["$files", "$folders"] } }
},
{
$unwind: "$folders"
},
{
$project: {
_id: "$folders._id",
name: "$folders.name",
parent: "$folders.parent",
user: "$folders.user",
isFile: "$folders.isFile",
fileSize: "$folders.fileSize",
fileMimetype: "$folders.fileMimetype",
shared: "$folders.shared",
createdAt: "$folders.createdAt",
updatedAt: "$folders.updatedAt"
}
},
вот результаты..
Nick
https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/
Al
Nick
выбирйте, там много стафа, как минимум пройдитесь по всему, чтобы не задавать таких вопросов
Nick
упс не на то скинул
Nick
https://docs.mongodb.com/manual/reference/operator/aggregation/
Nick
во
Nick
если западло все перебирать - вот список операторов для работы с массивами, коим ваш shared и является
https://docs.mongodb.com/manual/reference/operator/aggregation/#array-expression-operators
Al
если западло все перебирать - вот список операторов для работы с массивами, коим ваш shared и является
https://docs.mongodb.com/manual/reference/operator/aggregation/#array-expression-operators
const folders = await this.aggregate([
{ $match: { parent: ObjectId(folderId), deletedAt: null } },
{
$facet: {
folders: [
{
$match: {
isFile: false
}
},
{
$sort: sortCondition
}
],
files: [
{
$match: {
isFile: true
}
},
{
$sort: sortCondition
}
]
}
},
{
$project: { folders: { $concatArrays: foldersUp ? ["$folders", "$files"] : ["$files", "$folders"] } }
},
{
$unwind: "$folders"
},
{
$lookup: {
from: "folders",
localField: "folders._id",
foreignField: "linkedTo",
as: "shared"
}
},
{
$project: {
_id: "$folders._id",
name: "$folders.name",
parent: "$folders.parent",
user: "$folders.user",
isFile: "$folders.isFile",
fileSize: "$folders.fileSize",
fileMimetype: "$folders.fileMimetype",
shared: "$shared",
size: { $size: "$shared" },
createdAt: "$folders.createdAt",
updatedAt: "$folders.updatedAt"
}
},
{
$skip: skip
},
{
$limit: perPage
}
]).exec()
посмотрите верно в итоге?
Nick
вам виднее что в итоге
Al
lookup вынес из facet далеко в низ тк иначе shared был не определен в нижнем facet и sum ругался..
Nick
я вот sum в упор не вижу, да не особо то и надо. вам бы свою задачу написать сначала коде над нативными данными, а потом уже переносить на бд, если тяжело сразу в бд
Vova
Документ:
{
"_id": 1,
"Comments": [
{
"CommentId": 1,
"CommentText": "Fine"
},
{
"CommentId": 2,
"CommentText": "Good"
},
{
"CommentId": 3,
"CommentText": "Well done"
}
]
}
Результат выполнения запроса:
1) Объект с CommentId: 2 удаляется
2) Объекты с CommentId: >2 сдвигается на -1
3) Объекты с CommentId: <2 без изменений
Запрос:
updateOne({ _id: 1 },
{ $pull: { Comments: { CommentId: 2 } }, $inc: { "Comments.$[a].CommentId": -1 } },
{ arrayFilters: [ { "a.CommentId": { $gt: 2 } } ] })
Upd: попробовал через mongo консоль, пишет что конфликт при записи. Так-то запрос составлен правильно. Подскажите, как можно переписать чтобы не конфликтовало? Я не верю что это невозможно)
WriteError: Updating the path 'Comments.$[a].CommentId' would create a conflict at 'Comments'
Al
Al
другой вопрос производительность... а если связанных тысячи...
Al
но запрос в цикле уже из приложения еще хуже...
Nick
Vova
Жаль, я уже так и сделал
Nick
Vova
Работает, по отдельности
✙ Isliam ✙
блятт
✙ Isliam ✙
не туда
✙ Isliam ✙
вова ты и тут нихуя себе
Vova
s0menickname
@dd_bb
Igor
Коллеги, продолжая изучать монгу на проде:
Я сейчас пытаюсь доделать фильтр. У меня получился такой контроллер:
https://gist.github.com/exdeniz/fb6e545c68dbebd1844163acbc3097d9#file-bike-js-L29
Вопросы такие:
При $limit и $skip работает все шустро.
Но когда включаешь $faceit в конце, что бы посчитать total для выборки, начинаются тормоза. Около 15-30 секунд запрос.
Как в монге правильно это делается, я так понимаю один из путей убрать lookup и match по ним.
Igor
Количество записей где-то 200к, растут каждую неделю на 10к
Igor
Монга 3.4
倫太郎
Igor
Да соглашусь кончено.
倫太郎
и при проблемах, сначала надо подумать о версии продукта, может при обновлении пофиксится и т.д.
Igor
Мне кажется тут не фиксы, а моя безграмотность скорее
倫太郎
ну попробуй обновить, может поможет
Igor
Не помогло, стало даже медленее.
Igor
В лоб не решилось
Al
А можете просвятить... если я не использую aggregate то не могу групировать поля, как в project итп?
Например
const folderUsers = await this.find({ linkedTo: ObjectId(folder._id) })
.populate("user", { name: 1, email: 1 })
.select({ access: 1, user: 1 })
Al
выдает. вот такую структуру. Это верно. Но еще хотелось бы раскрыть вложенный user .
Al
я могу это сделать только переписав на aggregate и заменив populate на lookup?
AstraSerg
lookup есть только в aggragate
Al
lookup есть только в aggragate
это понятно. а populate как понял только НЕ в aggregate ... и если мне нужно, что то типа join и aggregate то придется вместо populate делать lookup...
Dmitry
Ребят, для запуска запуска монги (macos) надо каждый раз вызывать последовательно mongod и mongo ?
Bandikoot
Dmitry
ну допустим я вс код открываю и если у меня приложение использует локалхост, то я должен обе команды вводить? (первая как я понимаю запускает сервер, а вторая?)
Bandikoot
Dmitry
вот что по каманде монго выдает, как я понимаю прослушивание включается?
Bandikoot
ну да, это просто консольный клиент
Dmitry
Пугает строчка с WARNING
Bandikoot
это вам клиент передаёт те предупреждения, которые сервер при старте сгенерил
Dmitry
так сервер встал на дефолтую /data/db
Dmitry
И Read&write я этим папкам включил (everyone)
Bandikoot
расположение данных задаётся в конфиге сервера /etc/mongod.conf. давать на эту директорию доступ всем-всем не обязательно, достаточно тому пользователю, под которым запускается сервер. но на локальной тачке особо нет смысла заморачиваться, а на нормальном сервере такое (под кем запускается, проверка unix-прав директории с базами) стоит конфигурить через systemd
Dmitry
спасибо
Dmitry
да не я чисто для себя, думал перед сном чатик запилить на монго+сокетио
Dmitry
опробовать, так сказать, технологии)
Dmitry
и еще вопрос: я до этого делал на MERN простое to-do-app (использовал БД с mlab.com, там чисто в БД писались id и текст, а если это уже будет к примеру гостевая книга и пользователь захочет картинку загрузить? не пойму как в json формат она будет записываться?
Bandikoot
и еще вопрос: я до этого делал на MERN простое to-do-app (использовал БД с mlab.com, там чисто в БД писались id и текст, а если это уже будет к примеру гостевая книга и пользователь захочет картинку загрузить? не пойму как в json формат она будет записываться?
во-первых, надо помнить, что внутри у монги не json, а BSON на уровне хранилища
во-вторых, для хранения самих файлов монга, пожалуй, не самый лучший вариант, но это реализуемо через GridFS (https://www.mongodb.com/blog/post/storing-large-objects-and-files-in-mongodb)
в-третьих, почему бы не хранить вместо файлов ссылку на них в более подходящем сторадже (взять хотя бы s3)?
Dmitry
Спасибо за информацию! Буду изучать офиц документацию
Анатолий
вопрос - если выставить лимит по storage.wiredTiger.engineConfig.cacheSizeGB - mongodb будет всё равно использовать всю свободную память?
Анатолий
кто нибудь?
Федор
Она забьет ровно столько, сколько ты поставил размер кэша, либо меньше
Анатолий
но ведь написано что это только внутренний кэш который использует монга. а сверх этого используется системный кэш
Анатолий
With WiredTiger, MongoDB utilizes both the WiredTiger internal cache and the filesystem cache.
Анатолий
Via the filesystem cache, MongoDB automatically uses all free memory that is not used by the WiredTiger cache or by other processes.
Анатолий
The storage.wiredTiger.engineConfig.cacheSizeGB limits the size of the WiredTiger internal cache. The operating system will use the available free memory for filesystem cache, which allows the compressed MongoDB data files to stay in memory. In addition, the operating system will use any free RAM to buffer file system blocks and file system cache.
Анатолий
вот я и пытаюсь понять про "вся свободная RAM будет использована"
Анатолий
у меня на одном сервере MongoDB и Redis. машина на 128Гб RAM.
Redis постоянно вылетает с "cannot allocate memory" - а если перезагрузить MongoDB (высвобождает всю занятую память) тут же находит память и сохраняет данные на диск
Анатолий
при это всякие мониторинги показывают что куча свободной памяти постоянно.
AstraSerg
Это видимо про кеши файловой системы. Это поведкние современных ОС. Прочитанные из ФС файлы (в том числе файлы БД) хранятся в кешах. Если БД остановить, то эти кеши освобождтся, если место понадобится работоющим процессам.
Анатолий
ну вот всё дело в том что почему-то когда место в RAM требуется Redis - он его найти не может
AstraSerg
Вы говорили, что редис находит память, если остановить монгу. Или я не верно вас понял?
Федор
Кто-нибудь знает, что значит protocol:op_msg 127ms в логе монги? появляется в строках с типом COMMAND
Федор
значение, естественно, для каждой команды разное
Nick
Nick