我有一个MongoDBusers
集合,具有(简化的(文档结构:
{
_id: ObjectId,
name: 'John Doe',
sportsList: [ // array of objects
{
name: 'football',
level: 1500,
levelHistory: [ // array of objects
{
from: 1450,
to: 1500,
date: Date
},
...
]
},
{
name: 'tennis',
level: 1400,
levelHistory: [ // array of objects
{
from: 1350,
to: 1400,
date: Date
},
...
]
},
]
}
我想更新具有name === 'tennis'
的sportsList
的元素,如下所示:
- 将新元素推入
levelHistory
- 更新
level
到目前为止,我已经通过以下查询将一个新元素推送到levelHistory
中:
await User.updateOne(
{
_id: userId,
sportsList: {
$elemMatch: { name: 'tennis' }
}
},
{
$push: {
'sportsList.$.levelHistory': {
date: Date,
from: 1400,
to: 1450
}
},
// how do I set 'level: 1450' in the same query?
// if I tried to use a $set: { 'sportsList.$.level': 1450 } mongoDB throws an error
}
)
查询
- 管道更新需要MongoDB>=4.2
- 阵列上的映射
- 如果name不是网球,不要更改元素
- 否则,将元素(嵌入文档(与具有新级别和新级别History(旧元素与新元素的连接(的文档合并
PlayMongo
update(
{"_id": 1},
[{"$set":
{"sportsList":
{"$map":
{"input": "$sportsList",
"in":
{"$cond":
[{"$ne": ["$$this.name", "tennis"]}, "$$this",
{"$mergeObjects":
["$$this",
{"level": 1450,
"levelHistory":
{"$concatArrays":
["$$this.levelHistory",
[{"from": 1400, "to": 1450, "date": 4}]]}}]}]}}}}}])