更新 MongoDB 中的嵌套对象(如果存在),否则添加它

2023-12-07

我在 mongoDB 中有一个像这样的 json 文档:

 { "_id" : ObjectId("57ed88c0965bedd2b11d5727"),
   "refid" : 2,
   "votes" : [
     { "ip" : "127.0.2.1", "rating" : 5 },
     { "ip" : "127.0.3.1", "rating" : 2 },
     { "ip" : "127.59.83.210", "rating" : 50 },
     { "ip" : "127.56.26.191", "rating" : 5 },
     { "ip" : "127.59.83.210", "rating" : 5 },
     { "ip" : "127.59.83.210", "rating" : 30 }
    ]
 }

我不想为每个 IP 创建重复项,而是希望更新找到的记录(如果 IP 存在),或者添加新条目(如果不存在)。关于如何进行类似操作的问题有很多,但我找不到一个能准确询问如此简单的问题的问题。我正在 Node.js 中尝试:

db.collection('ratings').update( { "refid":refid, "votes.ip":ip },
  {
    $push: { votes: { "ip":ip, "rating":rating }
  }
})

但当我从同一个 IP 投票时,它只会不断添加新条目。

NOTE:我没有使用猫鼬。

如果我的问题过于简单,我很抱歉,我对 MongoDB 还很陌生。我只是想知道是否有一种好的方法可以做到这一点,而不是以编程方式迭代“投票”中的每条记录。谢谢!

EDIT:我所问的问题目前是不可能的,我已将下面的答案标记为正确,其中包含解释和 MongoDB 增强功能票证的链接。

至于我的问题中的场景,下面的代码适合我。我不知道它的性能有多好或多坏,但它涵盖了所有这些场景:

  • 如果该记录根本不存在,则创建它
  • 如果记录存在,则查找IP,如果找到,则更新评级
  • 如果记录存在但IP不存在,则插入新的评级

Works:

db.collection('ratings').findOne({ "refid":refid }).then(function(vote) {  
  if (vote == null) {
    newrating = {refid: refid, votes: [{ ip: ip, rating: rating }]};
    db.collection('ratings').save(newrating);
  } else {
    db.collection('ratings').findOne({ "refid":refid, "votes.ip":ip }).then(function(rate) {
      if (rate != null) {
        db.collection('ratings').update(
          { refid: refid, "votes.ip" : ip },
          { $set: { "votes.$.rating" : rating } }
        )
      } else {
        db.collection('ratings').update({"refid":refid,"votes.ip" : {$ne : ip }},
          { $push: { votes: { "ip" : ip, "rating" : rating, }}}
        )
      }
    })
  }
})

要插入文档(如果不存在)是通过 upsert 完成的,如果要更新条件嵌入文档,则需要 $ 位置运算符。因此,您需要在查询中使用两者来实现上述功能。

但现在 mongodb 不支持使用 $ 位置运算符更新插入

不要将位置运算符 $ 与 upsert 操作一起使用,因为: inserts 将使用 $ 作为插入文档中的字段名称。

因此,您想要的目前不可能在一个查询中完成,或者您可以在两个查询中完成。

First

db.collection('ratings').update(
  {"refid":refid, "votes.ip": ip},
  {
     $set: { "votes.$.rating":rating }
  }
)

它返回更新的文档数,如果是1就可以,如果是0则需要推送新记录。

db.collection('ratings').update( { "refid":refid, "votes.ip":{$ne: ip}},
    {$push: { votes: { "ip":ip , "rating":rating  }}
})

还有用于位置运算符和更新插入的 jira 票证,如果您想在 mongodb 中使用此功能,请为此问题投票。以下是问题链接

https://jira.mongodb.org/browse/SERVER-3326

(EDIT:jira 票证已关闭Won't Do2019 年 6 月)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更新 MongoDB 中的嵌套对象(如果存在),否则添加它 的相关文章

随机推荐