yopp
Можно ещё Attribute Value, но в данном случае это скорее всего не требуется:
{ constants: [
{name: 'foo', value: 1},
{name: 'bar', value: 2},
]}
Anonymous
> db.regions.find();
{ "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" }
{ "_id" : ObjectId("605338dc9565528893b347ba"), "name" : "Московская область" }
> db.cities.find();
{ "_id" : ObjectId("605339039565528893b347bb"), "name" : "Рязань", "regionid" : "605338dc9565528893b347b9" }
{ "_id" : ObjectId("605339039565528893b347bc"), "name" : "Спасск", "regionid" : "605338dc9565528893b347b9" }
{ "_id" : ObjectId("605339039565528893b347bd"), "name" : "Коломна", "regionid" : "605338dc9565528893b347ba" }
>
Надо вывести Города (из cities коллекции), чтобы они еще и имели указание Региона (из regions-коллекции):
> db.cities.aggregate([ {$lookup: {from: "regions", localField: "regionid", foreignField: "_id", as: "result"}} ])
{ "_id" : ObjectId("605339039565528893b347bb"), "name" : "Рязань", "regionid" : "605338dc9565528893b347b9", "result" : [ ] }
{ "_id" : ObjectId("605339039565528893b347bc"), "name" : "Спасск", "regionid" : "605338dc9565528893b347b9", "result" : [ ] }
{ "_id" : ObjectId("605339039565528893b347bd"), "name" : "Коломна", "regionid" : "605338dc9565528893b347ba", "result" : [ ] }
>
В result[], где предполагается выводиться Регион - пустота. Это из-за того, что cities.regionid - это строка. А его аналог foreign-key, regions._id = Объект. Ни $toString(), ни $addFields, ни $project не помогают! Версия 4.2.
Anonymous
Привет!
Anonymous
уже 2 дня трахаюсь...
Vitalii
а переводить regionid в ObjectId?
Vitalii
пробовали?
Anonymous
не пашет
yopp
не пашет
Вам необходимо хранить в cities regoinid в типе ObjectId. Так как $lookup будет делать запрос по _id коллекии регионов, а нам наверняка _id в ObjectId, а не строкой
Anonymous
дык проще уж тогда первичный ключ в regions _id пихать как строку а не объект
Anonymous
но имеем что имеем
Vitalii
https://ibb.co/TvxCn39
Vitalii
я могу ошибаться, но по моему не получится делать агрегацию с коллекции cities, а переводить _id  из коллекции regions в строку
Vitalii
нужно работать с текущей коллекцией
Anonymous
> db.cities.aggregate([ {$addFields: {regObjId: {$toObjectId: "$regionid"}}}, {$lookup: {from: "regions", localField: "regObjId", foreignField: "_id", as: "result"}} ])
{ "_id" : ObjectId("605339039565528893b347bb"), "name" : "Рязань", "regionid" : "605338dc9565528893b347b9", "regObjId" : ObjectId("605338dc9565528893b347b9"), "result" : [ { "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" } ] }
{ "_id" : ObjectId("605339039565528893b347bc"), "name" : "Спасск", "regionid" : "605338dc9565528893b347b9", "regObjId" : ObjectId("605338dc9565528893b347b9"), "result" : [ { "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" } ] }
{ "_id" : ObjectId("605339039565528893b347bd"), "name" : "Коломна", "regionid" : "605338dc9565528893b347ba", "regObjId" : ObjectId("605338dc9565528893b347ba"), "result" : [ { "_id" : ObjectId("605338dc9565528893b347ba"), "name" : "Московская область" } ] }
Anonymous
браво! Виталий спасибо!
Vitalii
👍
Anonymous
кстати а как утт только определенные поля вывести? безо всяких _id? В обычных find(0 запросах это не проблема, но тут...
Vitalii
db.cities.aggregate([{$addFields:{regObjId:{$toObjectId:"$regionid"}}},{$lookup:{from:"regions",localField:"regObjId",foreignField:"_id",as:"result"}},{$project:{_id:0}}])
Vitalii
я обычно вручную выставляю поля в $project
Vitalii
может быть есть какой-то более верный способ
Anonymous
ааа так это в $project указывается - спасибо - прочту про него внимательнее
Anonymous
> db.cities.aggregate([ {$addFields: {regObjId: {$toObjectId: "$regionid"}}}, {$lookup: {from: "regions", localField: "regObjId", foreignField: "_id", as: "result"}}, {$project: {_id: 0, regionid: 0, regObjId: 0}} ])
{ "name" : "Рязань", "result" : [ { "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" } ] }
{ "name" : "Спасск", "result" : [ { "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" } ] }
{ "name" : "Коломна", "result" : [ { "_id" : ObjectId("605338dc9565528893b347ba"), "name" : "Московская область" } ] } - удалил лишнее.... А реально сделать чтобы не было этого resulе, а просто было ...regionname: "Московская Область"
Никита
Может кто сталкивался с подобным:
MongoDB 3.6 -> 4.2 в яндексе перенес. После переноса сайт дико тупит. На 3.6 - все норм работает. Монгус 5.11.15 версии (почти свежак). Никак понять не могу в чем дело...
может есть инструмент какой-то, который запишет результаты выполнения запросов в файл или в лог для анализа (запросов много, раскопать почему тупить начинает очень сложно)
Vitalii
> db.cities.aggregate([ {$addFields: {regObjId: {$toObjectId: "$regionid"}}}, {$lookup: {from: "regions", localField: "regObjId", foreignField: "_id", as: "result"}}, {$project: {_id: 0, regionid: 0, regObjId: 0}} ])
{ "name" : "Рязань", "result" : [ { "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" } ] }
{ "name" : "Спасск", "result" : [ { "_id" : ObjectId("605338dc9565528893b347b9"), "name" : "Рязанская область" } ] }
{ "name" : "Коломна", "result" : [ { "_id" : ObjectId("605338dc9565528893b347ba"), "name" : "Московская область" } ] } - удалил лишнее.... А реально сделать чтобы не было этого resulе, а просто было ...regionname: "Московская Область"
db.cities.aggregate([{$addFields:{regObjId:{$toObjectId:"$regionid"}}},{$lookup:{from:"regions",localField:"regObjId",foreignField:"_id",as:"result"}},{$project:{_id:0,regionid:0,regObjId:0}},{$unwind:{path:'$result'}},{$addFields:{regionname:'$result.name',}},{$unset:'result'}])
Anonymous
спасибо! сейчас буду разбираться с этой конструкцией
kk
У меня есть замечательная (нет) идея: есть ли механизм на уровне драйвера/бд который бы откидывал запросы не использующие индексы? Допустим аггрегации не берём, find(). Или это только постфактум можно делать, алертя на логи с COLLSCAN/docsExamined>N ?
yopp
kk
yopp
спасибо большое)
там в конце очень важное замечение про использование в продакшене :)
yopp
(== не стоит)
kk
блин, жаль на коллекции нельзя выставить
Google
Всем привет как исправить монгодб
Google
не могу зупустить монгов Centos 8
Melonges
mongoose используется для облачной бд?
Maxim
Всем привет, начал изучать Монго, до этого работал из дома и сейчас пришел в офис и теперь не понимаю как в кластере сменить IP
Maxim
подскажите пожалуйста
Максим
Maxim
Да
Максим
Да
Не помню где, но там есть такая настройка. Потыкай в интерфейс. Или может кто подскажет.
Maxim
окей)
Maxim
О, спасибо большое)
Максим
там где нули у меня, напиши свой ип
Maxim
Разобрался
Maxim
А как же тут указать какие параметры?
Maxim
Понимаю что TS, но схема описания для монгуса
Anatoly
Привет. подскажите как правильно работать с транзакциями в монге. Есть такой код session = await mongoose.connection.startSession();
session.startTransaction();
try {
updatedWallet = await walletModel.findOneAndUpdate(
{
accountId,
type,
},
{
$inc: {
balance,
},
},
{ session: session, new: true },
);
createTransaction = await transactionModel.create({
walletId: updatedWallet._id,
direction,
amount: Math.abs(balance),
reason,
meta: omitBy(meta, isNil),
walletType: type,
accountId: updatedWallet.accountId,
},
{ session: session, new: true },
);
} catch(e) {
await session.abortTransaction();
session.endSession(); throw new Error(e);
}
await session.commitTransaction();
session.endSession(); это работает как ожидается до тех пор пока не делаются параллельные запросы через Promise.All([несколько вызовов сразу]). В этот момент выполняется первый запрос а второй отлетает с ошибкой writeconflict.
yopp
Привет. подскажите как правильно работать с транзакциями в монге. Есть такой код session = await mongoose.connection.startSession();
session.startTransaction();
try {
updatedWallet = await walletModel.findOneAndUpdate(
{
accountId,
type,
},
{
$inc: {
balance,
},
},
{ session: session, new: true },
);
createTransaction = await transactionModel.create({
walletId: updatedWallet._id,
direction,
amount: Math.abs(balance),
reason,
meta: omitBy(meta, isNil),
walletType: type,
accountId: updatedWallet.accountId,
},
{ session: session, new: true },
);
} catch(e) {
await session.abortTransaction();
session.endSession(); throw new Error(e);
}
await session.commitTransaction();
session.endSession(); это работает как ожидается до тех пор пока не делаются параллельные запросы через Promise.All([несколько вызовов сразу]). В этот момент выполняется первый запрос а второй отлетает с ошибкой writeconflict.
WriteConflict это корректное поведение. Если несколько транзакций изменяют один документ, только одна транзакция сможет сделать коммит, остальные будут отменены с WriteConflict. Разрешение конфликта остаётся на усмотрение приложения
yopp
Самый простой вариант: вынести всю подготовку данных и транзакцию в отдельный метод, так чтоб полностью изолировать вычисление нового состояния, завернуть его в try/catch и делать retry когда случается конфликт.
Anatoly
Ilya
всем привет, почему при передаче в метод .count фильтра с 2 полями - всегда возвращает 0?
Ilya
мб я что-то не так делаю
Ilya
model.countDocuments({ field1: 'test', field2: 'test' })
yopp
Ilya
yopp
countDocuments(query) это эквивалент find(query).count
yopp
Если вы хотите условие ИЛИ, то используйте $or: [cond, cond]
Ilya
я разобрался, не то передавал
Maxim
Melonges
у кого-нибудь получалось ставить локально бд на mac?
Melonges
yopp
Вы запускаете команду mongo, а это mongo shell: консольный интерактивный инструмент для взаимодействия с базой, но для него нужен сервер. Сам сервер это mongod, наверное он в этой-же поставке. Необходимо запустить сначала его, а потом уже к нему подключится.
Но проще будет поставить из homebrew, так как там не надо будет ничего настраивать и сервер будет запускаться автоматически при старте системы. Плюс обновлять легче
Melonges
понял, спасибо
Melonges
А все пользуются компасом, никто не пользуется datagrip от jetbrains?
Amirbek
Добрый вечер. Кто делал деплой ? Mongoose connect как писать ? В локале норм работает а заливаю на сервер ошибка
Vladyslav
yopp
Zaur
коллеги, подскажите где можно почитать подробности про вывод explain. Что означает каждый параметр и как вообще читать этот вывод? Это хороший результат или плохо ....
Sharyar
Всем привет. Как можно в модели описать схему координат? например:
coords: {
lat: xx.xxxxxx,
lon: xx.xxxxx,
}
yopp
коллеги, подскажите где можно почитать подробности про вывод explain. Что означает каждый параметр и как вообще читать этот вывод? Это хороший результат или плохо ....
Это вывод о том, какую стратегию выбрал планировщик для выполнения запроса.
В первую очередь тут интересен сам план, указанный в winningPlan. Читается он в обратном порядке, от конца к началу.
У вас первый шаг это IXSCAN, это поиск по индексу. В keyPattern видны поля которые будут использоваться для поиска по индексу. Где-то ниже будет поле shape, которое определяет диапазон ключей индекса по которым будет происходить поиск.
FETCH это загрузка полного документа из результата поиска по индексу
А SIMPLE PROJECTION это шаг выполняющий проекцию: трансформацию документа с удалением ненужных полей.
Но сам план это не самая информативная часть, так как это только план.
Интереснее сразу смотреть на то как план реально исполняется: для этого необходимо выполнить эксплейн с таким ключом explain({executionStats:true})
Там вы уже увидите статистику сколько времени занимает выполнение каждого шага. Там будет три ключевые метрики keysScanned, docsScanned и docsReturned. Первое это сколько ключей индекса потреблялось прочитать чтоб найти нужный результат. Второе сколько документов пришлось целиком просмотреть и третье это итоговое время выполнение шага в миллисекундах
Наиболее эффективно когда первый шаг IXSCAN. Если первый шаг COLLSCAN то на больших объемах будут проблемы.
Общий подход: docsReturned должен стремиться к keysScanned — значит что все условия поиска были покрыты индексом и в дальнейшем выкидывать документы не пришлось.
docsScanned должен стремиться к keysScanned. Если docsScanned больше чем keysScanned, значит какая-то часть запроса выполняется мимо индекса
Идеально когда docsScanned равен нулю :) Это возможно с covered queries.
Ну и чем меньше приходится просматривать документов или индексов, тем быстрее будет запрос
Zaur
Speedy
Класс
Константин
Ребзя, help me please. Пытаюсь подключить монго к nestjs, и настроить простой поиск. В монге для коллекции сделал create search index, но при попытке поиска получаю ошибку MongoError: text index required for $text query. Подскажите пожалуйста что я не так делаю?
Nick
Физик-ядерщик
Подскажите пожалуйста, как можно удалить элемент из массива по его индексу?
Deni
Slice+spread
Ilya