如果存在,请更新MongoDB中的嵌套对象,否则添加它 [英] Update nested object in MongoDB if it exists, otherwise add it
问题描述
我在mongoDB中有一个像这样的json文档:
I've got a json doc like this in mongoDB:
{ "_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中尝试此操作:
And instead of creating dupes per IP, I want to update the record found if the IP exists, or add a new entry if it doesn't. There are tons of questions on how to do similar operations, but none that I could find exactly asking something this simple. I am trying this in Node.js:
db.collection('ratings').update( { "refid":refid, "votes.ip":ip },
{
$push: { votes: { "ip":ip, "rating":rating }
}
})
但是当我从同一IP投票时,它只会不断添加新条目.
But it just keeps adding new entries when I vote from the same IP.
注意::我不使用猫鼬.
我很抱歉,如果我的问题过于基础,我对MongoDB还是陌生的.我只是想知道是否有一个很好的方法来完成此任务,而不是以编程方式遍历投票"中的每条记录.谢谢!
I apologize if my question is overly elementary, I'm pretty new to MongoDB. I'm just wondering if there's a good way to do this baked in rather than iterating through every record in "votes" programmatically. Thanks!
编辑:我目前无法提出要求,我在下方标记了一个正确的答案,其中包含解释和指向MongoDB的票证链接以进行增强.
What I'm asking isn't currently possible, I've marked an answer below correct which contains the explanation and a link to a ticket at MongoDB for an enhancement.
至于我在此问题中的情况,下面的代码对我有用.我不知道在性能方面有多好,但它涵盖了所有这些情况:
As for the scenario in my question here, the code below works for me. I have no idea how good or bad it is performance wise, but it covers all of these scenarios:
- 如果记录根本不存在,请创建它
- 如果记录存在,请查找IP,如果找到,请更新评级
- 如果记录存在,但IP不存在,请插入新的评分
作品:
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完成的,如果要更新条件嵌入式文档,则需要$位置运算符.因此,您需要在查询中同时使用两者来实现上述功能.
To insert a document if not exist is done by upsert and if you want to update a conditional embedded document you need $ positional operator. So you need to use both in query to implement above functionality.
但是现在mongodb不支持使用$位置运算符进行加粗
请勿将位置运算符$与upsert操作一起使用,因为, 插入将使用$作为插入文档中的字段名称.
Do not use the positional operator $ with upsert operations because, inserts will use the $ as a field name in the inserted document.
因此,您目前无法在一个查询中执行此操作,或者您可以在两个查询中执行操作.
第一
db.collection('ratings')).update(
{"refid":refid, "votes.ip": ip},
{
$set: { "votes.$.rating":rating }
}
)
它返回更新的文档数,如果为1则可以,如果为0,则需要推送新记录.
It returns the number of documents updated, if it is 1 it's fine, and if it is 0 you need to push new record.
db.collection('ratings')).update( { "refid":refid, "votes.ip":{$ne: ip}},
{$push: { votes: { "ip":ip , "rating":rating }}
})
还有jira用于位置运算符和upserting的票证,如果您希望在mongodb中使用此功能,请plz投票给该问题.以下是问题的链接
There also jira ticket for positional operator and upserting, plz vote for this issue if you want this functionality in mongodb. Below is the link of issue
https://jira.mongodb.org/browse/SERVER-3326
这篇关于如果存在,请更新MongoDB中的嵌套对象,否则添加它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!