Al
То есть пока, что у данного юзера lastEmailSend вообще нету. Но я думал таким запросом как раз можно создать его
Al
может тут как то с $push
Al
> db.users.update({ email: "htchtc052@gmail.com"}, { $set: {"lastEmailSend.$.sendedAt": new Date() } }, {upsert: true } ) WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 2, "errmsg" : "The positional operator did not find the match needed from the query." }
Al
Вот в чем дело: "upsert Do not use the positional operator $ with upsert operations because inserts will use the $ as a field name in the inserted document."
Al
В общем к сож. никак
yopp
db.array12.update( { "some_id": 182315381, "docs": { $elemMatch: {type: {$eq: "corn"}} } }, { $inc: { "docs.$.qty": 1 } }, { upsert: true, new: true } );
yopp
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.array12.find({}) { "_id" : ObjectId("5dcb1cb63f0ae2bbb1056699"), "some_id" : 182315381, "docs" : [ { "type" : "corn", "qty" : 3 } ] }
yopp
только вместо $inc у вас $set
yopp
в 4.2 по крайней мере работает)
Ivan
привет! Какова вероятность, что mongo 4.0 бекпортнут на debian10? Про 3.6 уже не заикаюсь
yopp
никакой
Ivan
Класс, спасибо!
yopp
используйте 4.2
yopp
если не включать featureCompat то это drop-in replacement для 4.0
yopp
только что баги будут поновнее
Ivan
Благодарю
yopp
был неправ в прошлом сообщении. у меня протёк существующий документ. с positional не прокатывает короч. До 4.2 только двумя запросами, в 4.2 вот таким вот клёвым образом: db.array15.findAndModify({ query: { "some_id": 182315386 }, update: [ { // Ensure that `docs` key is never null, otherwise $if will fail $set: { "docs": { $ifNull: [ "$docs", [] ] } } }, { $set: { "docs": { $cond: { // Check if sub-document with `type: 'wood'` already exists if: { $in: ["wood", "$docs.type"] }, // If exists, then: { // then iterate over array of subdocuments in $doc $map: { input: "$docs", as: "current", in: { $cond: { // And when current subdocument got `type: 'wood'` if: { $eq: ["$$current.type", "wood"] }, then: { // Update current subdocument $mergeObjects: [ "$$current", { // By adding 1 to the current value of qty qty: { $sum: ["$$current.qty", 1] } } ] }, // Otherwise just return original subdocument else: "$$current" } } } }, // If there is no subdocument, else: { // then just add the new subdocument to the `docs` array $concatArrays: [ [ { type: "wood", qty: 1 } ], "$docs" ] } } // $cond } // "docs" } // $set } ], upsert: true, "new": true })
yopp
где мой PhD по агрегатологии вообще
yopp
и когда 4.2 уже на m0 завезут
Al
был неправ в прошлом сообщении. у меня протёк существующий документ. с positional не прокатывает короч. До 4.2 только двумя запросами, в 4.2 вот таким вот клёвым образом: db.array15.findAndModify({ query: { "some_id": 182315386 }, update: [ { // Ensure that `docs` key is never null, otherwise $if will fail $set: { "docs": { $ifNull: [ "$docs", [] ] } } }, { $set: { "docs": { $cond: { // Check if sub-document with `type: 'wood'` already exists if: { $in: ["wood", "$docs.type"] }, // If exists, then: { // then iterate over array of subdocuments in $doc $map: { input: "$docs", as: "current", in: { $cond: { // And when current subdocument got `type: 'wood'` if: { $eq: ["$$current.type", "wood"] }, then: { // Update current subdocument $mergeObjects: [ "$$current", { // By adding 1 to the current value of qty qty: { $sum: ["$$current.qty", 1] } } ] }, // Otherwise just return original subdocument else: "$$current" } } } }, // If there is no subdocument, else: { // then just add the new subdocument to the `docs` array $concatArrays: [ [ { type: "wood", qty: 1 } ], "$docs" ] } } // $cond } // "docs" } // $set } ], upsert: true, "new": true })
Ужас. Из-за читабельности лучше двумя запросами. Или менять структуру коллекции
yopp
никакого ужаса, всё предельно ясно
yopp
менять структуру некуда
yopp
потому что изменение структуры это сразу досвиданья индексам
yopp
два запроса в транзакции тоже можно
yopp
но там задача стояла одним ударом сделать. вот один удар :)
yopp
весело
yopp
атомарно!
yopp
самое некрасивое там $mergeObjects, от которого внутри $map никуда не деться, к сожалению
yopp
воще AF в update адски мощный инструмент
yopp
наверное можно даже тетрис написать, если постараться
Josh
где мой PhD по агрегатологии вообще
забавное решение, на плейграунде не удается тестануть, там не 4.2 да? https://play.db-ai.co/m/XchUt2jklgABiNax/edit?key=YWRza16I9NQ
yopp
Да, там 4.0.х
Josh
Да, там 4.0.х
без мапы пушем или добавлением не обойтись разве?
yopp
$push а AF нет.
yopp
Он есть в $group с другой семантикой
yopp
Тут всё вполне тривиально: если элемента нет, то добавляем, а если есть то находим и обновляем.
Josh
при реструктуризации получается не менее засраный код, кстати, потому что приходится агрегацией запрос делать с 2х коллекций
yopp
Да не особо
yopp
Там скобочки полдокумента занимают
Josh
да норм решение, короче не вижу как сделать, все красиво
yopp
Мне тут единственное что не очень нравится что массив по сути два раза обходить, из-за $in в условии. Но это микрооптимизация и а сходу не пришло в голову как сделать переменную, чтоб отсутсвие совпадений после $map проверять
yopp
Если только через $reduce наверное
yopp
Но читать будет сильно хуже чем сейчас, а o(2n) пока там не десятки тысяч элементов даже видно не будет нигде
Anonymous
Господа, подскажите, это нормально что монгу приходится выключать по kill -9 ?
Anonymous
Других способов выключить всю реплику не нашёл...
Dmitry
Логика вроде верная, на питоне ложится в одну строку вообще, а здесь не понимаю как сделать 🤷‍♂️
Dmitry
к каждому элементу массива leika (~словарь) я применяю arrayToObject
Arsen
Добрый день! У меня вопрос про change streams.
Arsen
Возможно ли при изменении поля документа получить также и его предыдущее значение ?
Arsen
Задача в том, чтобы сделать запрос с определенным фильтром, а потом отслеживать изменения.
Arsen
Тут возникает проблема, что если при изменении какой-нибудь документ перестаёт соответствовать условию фильтра, то я его не получаю в change stream
Nick
Тут возникает проблема, что если при изменении какой-нибудь документ перестаёт соответствовать условию фильтра, то я его не получаю в change stream
вы хотите аналог триггеров в обычных базах, где известны старые и новые значения колонок - в монге такого нет. Вам полюбому пересматривать подход к решению своей задачи, а может и саму задачу переиначить
Nick
бизнес задача какая?
Arsen
Задача - показывать некие отфильтрованные данные, которые меняются с довольно большой скоростью. Сейчас для этого используем RethinkDB, там есть всё что нужно, но проблемы с производительностью
Nick
почему не использоать нормальные события и очереди?
Arsen
а где тогда хранить snapshot ?
Nick
вы берете и при изменении состояния создаете событие которое пушите в очереди куданить. сама база остается как есть
Arsen
работает всё так - у нас есть снапшот и постоянный поток изменений. В любой момент клиент может запросить какое-то подмножество данных(т.е. с фильтром) на текущий момент и подписаться на изменения подмножества
Arsen
клиентов много, фильтры не фиксированные
yopp
Господа, подскажите, это нормально что монгу приходится выключать по kill -9 ?
https://docs.mongodb.com/manual/tutorial/manage-mongodb-processes/#use-shutdownserver Не очень нормально.
Nick
клиентов много, фильтры не фиксированные
нормальные очереди нужны и нормальные события, и создание событий для каждого пользователя свои
Arsen
можно пожалуйста поподробнее, что имеется в виду под событиями и в каком месте тогда фильтровать данные ?
Nick
всем привет, возвращаясь к вопросу. Попробовал реализовать так: {$project: {"_id":1, "leikaaa": { $reduce: { input: "$leika", initialValue: [], in: { $arrayToObject: {$literal : "$leika" }} } } }} Все равно не выходит, говорит arrayToObject просит array получает стринг
[ {"$project": {"_id":1, "leikaaa": { "$reduce": { "input": "$leika", "initialValue": [], "in": { "$concatArrays": [ "$$value", [{"$arrayToObject": [[{ "k":"$$this.parameter", "v":"$$this.value" } ]] }]] } } } }} ]
Dmitry
@yatoba ты крут
Dmitry
спасибо
Nick
Оно не совсем в том виде
yopp
Оно не совсем в том виде
ток вместо $reduce можно $map :)
yopp
тогда $concatArrays не надо
S
чтобы сортировать по дате создания обязательно указывать timestamps: true в схеме?
yopp
жаль что в именах ключей интерполяция не работет, тогда можно было вообще в $reduce тупо $mergeObject: [«$$value», {«$$this.key»: «$$this.value»}] и всё
yopp
а что ещё можно подразумевать в монге под интерполяцией кроме ${expr}?
Nick
https://play.db-ai.co/m/XcvafnFumAAB8J6u/edit?key=KXl9JmAFKX4