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
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
Ivan
Благодарю
ᅠ ᅠᅠ ᅠᅠ ᅠᅠ Alex S.
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
наверное можно даже тетрис написать, если постараться
yopp
Да, там 4.0.х
Josh
Да, там 4.0.х
без мапы пушем или добавлением не обойтись разве?
yopp
$push а AF нет.
yopp
Он есть в $group с другой семантикой
yopp
Тут всё вполне тривиально: если элемента нет, то добавляем, а если есть то находим и обновляем.
Josh
при реструктуризации получается не менее засраный код, кстати, потому что приходится агрегацией запрос делать с 2х коллекций
Josh
yopp
Да не особо
yopp
Там скобочки полдокумента занимают
Josh
да норм решение, короче не вижу как сделать, все красиво
yopp
Мне тут единственное что не очень нравится что массив по сути два раза обходить, из-за $in в условии. Но это микрооптимизация и а сходу не пришло в голову как сделать переменную, чтоб отсутсвие совпадений после $map проверять
yopp
Если только через $reduce наверное
yopp
Но читать будет сильно хуже чем сейчас, а o(2n) пока там не десятки тысяч элементов даже видно не будет нигде
Anonymous
Господа, подскажите, это нормально что монгу приходится выключать по kill -9 ?
Anonymous
Других способов выключить всю реплику не нашёл...
Dmitry
привет. Вопрос к спецам по запросам:
Хочу из текущей структуры
{
"_id" : "0000.0000.0000.0000.0000.0000.0000.0000",
"leika" : [
{
"value" : 9,
"parameter" : "id22"
},
{
"value" : 14,
"parameter" : "id27"
},
……
{
"value" : 3,
"parameter" : "id4"
}]}
Получить такую:
{
"_id" : "0000.0000.0000.0000.0000.0000.0000.0000",
"leika" : {id22: 9, id27:14,….,id4:3}
в документации нашел функцию - {$arrayToObject: "$field’}
но она не работает
всем привет,
возвращаясь к вопросу.
Попробовал реализовать так:
{$project: {"_id":1,
"leikaaa":
{
$reduce: {
input: "$leika",
initialValue: [],
in: { $arrayToObject: {$literal : "$leika" }}
}
}
}}
Все равно не выходит, говорит arrayToObject просит array получает стринг
Dmitry
Логика вроде верная, на питоне ложится в одну строку вообще, а здесь не понимаю как сделать 🤷♂️
Dmitry
к каждому элементу массива leika (~словарь) я применяю arrayToObject
Arsen
Добрый день! У меня вопрос про change streams.
Arsen
Возможно ли при изменении поля документа получить также и его предыдущее значение ?
Arsen
Задача в том, чтобы сделать запрос с определенным фильтром, а потом отслеживать изменения.
Arsen
Тут возникает проблема, что если при изменении какой-нибудь документ перестаёт соответствовать условию фильтра, то я его не получаю в change stream
Nick
бизнес задача какая?
Arsen
Задача - показывать некие отфильтрованные данные, которые меняются с довольно большой скоростью. Сейчас для этого используем RethinkDB, там есть всё что нужно, но проблемы с производительностью
Nick
почему не использоать нормальные события и очереди?
Arsen
а где тогда хранить snapshot ?
Nick
Nick
вы берете и при изменении состояния создаете событие которое пушите в очереди куданить. сама база остается как есть
Arsen
работает всё так - у нас есть снапшот и постоянный поток изменений. В любой момент клиент может запросить какое-то подмножество данных(т.е. с фильтром) на текущий момент и подписаться на изменения подмножества
Arsen
клиентов много, фильтры не фиксированные
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
тогда $concatArrays не надо
S
чтобы сортировать по дате создания обязательно указывать timestamps: true в схеме?
yopp
yopp
жаль что в именах ключей интерполяция не работет, тогда можно было вообще в $reduce тупо $mergeObject: [«$$value», {«$$this.key»: «$$this.value»}] и всё
Nick
yopp
а что ещё можно подразумевать в монге под интерполяцией кроме ${expr}?
Nick
https://play.db-ai.co/m/XcvafnFumAAB8J6u/edit?key=KXl9JmAFKX4