{
_id:'1',
name:'apple',
option:[{
weight:'10',
size:'40'
price:'40',
},
{weight:'40',
size:'40'
price:'200'}]
}
如果重量或大小不同,我想在阵列中插入新对象,如果大小和重量都匹配,我想更新它。我该怎么办?
答案 0 :(得分:1)
与your previous question类似,您使用的是.bulkWrite()
,但由于数组元素选择具有“多个条件”,因此您可以使用$elemMatch
:
db.collection.bulkWrite([
{ "updateOne": {
"filter": {
"_id": "1",
"option": {
"$elemMatch": { weight": "40", "size": "40" }
}
},
"update": {
"$set": { "option.$.price": "300" }
}
}},
{ "updateOne": {
"filter": {
"_id": "1",
"option": {
"$not": {
"$elemMatch": { weight": "40", "size": "40" }
}
}
},
"update": {
"$push": { "option": { "weight": "40", "size": "40", "price": "300" } }
}
}},
{ "updateOne": {
"filter": { "_id": 1 },
"update": {
"$setOnInsert": {
"option": [
{ "weight": "40", "size": "40", "price": "300" }
]
}
},
"upsert": true
}}
])
所以操作是:
测试$elemMatch
中匹配条件的数组元素是否存在,然后$set
匹配的值。
测试数组元素是否为$not
否定。您可以在每个属性上使用$ne
,但是否定两个匹配更清晰的条件。
"$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
无论如何,当找到与提供的条件匹配的不时,您$push
新数组元素。
仅在未找到主文档_id
的情况下尝试“upsert”,并使用$setOnInsert
以便在找到文档时此操作不执行任何操作。
与之前相同,尽管将整个批次发送到服务器,但其中只有一个实际上会写入任何内容。
答案 1 :(得分:0)
您可以通过一个仅限mongodb的操作将所有内容连接在一起,通过添加一个'版本'可能会更好。字段和使用乐观锁定,像java + spring-data为你做(google for @Version)。这将允许在持久性之前对完整对象进行复杂的更改和验证。