MongoDB实现:存在date则更新分数,否则新增记录
MongoDB嵌套数组的更新/新增逻辑优化
现有MongoDB文档结构如下:
{ "_id": "631337640754675725", "characters": [ { "name": "Druuwu", "scores": [ { "date": "2023-09-03", "score": 100 }, { "date": "2023-09-03", "score": 1000 }, { "date": "2023-09-03", "score": 101 }, { "date": "2023-09-03", "score": 102 } ] } ] }
当前使用的更新逻辑仅能通过$addToSet添加完全不重复的scores对象,无法处理同date不同score的更新需求:
await culvertSchema.findOneAndUpdate( { _id: interaction.user.id, "characters.name": selectedCharacter, }, { $addToSet: { "characters.$[index].scores": { score: culvertScore, date: reset }, }, }, { arrayFilters: [{ "index.name": selectedCharacter }], new: true, } );
解决方案
需要分两步处理:先尝试更新已存在的同date记录,若未找到匹配项则执行新增操作,具体实现如下:
- 第一步:更新已存在的同date分数记录
const updateResult = await culvertSchema.updateOne( { _id: interaction.user.id, "characters.name": selectedCharacter, "characters.scores.date": reset // 匹配该角色下存在指定date的score记录 }, { $set: { "characters.$[char].scores.$[scoreItem].score": culvertScore } }, { arrayFilters: [ { "char.name": selectedCharacter }, { "scoreItem.date": reset } ] } );
- 第二步:若未找到可更新的记录,则新增该date的分数项
if (updateResult.modifiedCount === 0) { await culvertSchema.findOneAndUpdate( { _id: interaction.user.id, "characters.name": selectedCharacter }, { $push: { // 已确认不存在同date记录,无需用$addToSet "characters.$[index].scores": { score: culvertScore, date: reset } } }, { arrayFilters: [{ "index.name": selectedCharacter }], new: true } ); }
逻辑说明
- 第一步通过
updateOne匹配目标用户、目标角色,且该角色下存在指定date的score记录,利用双arrayFilters分别定位目标角色和目标score项,直接更新score值。 - 通过
updateResult.modifiedCount判断是否有记录被更新:若为0,说明该date的score记录不存在,执行第二步的$push操作新增记录。
内容的提问来源于stack exchange,提问作者Hypo
相关产品推荐
相关产品推荐

