假设我有这个收藏夹:
db.item.find().pretty()
{
"_id" : ObjectId("5c5635194b6929067972b85c"),
"name" : "car",
"attributes" : [
{
"color" : "blue",
"qty" : 10
}
]
}
如果不存在嵌入的“属性”文档,我想添加一个新条目,否则仅进行更新。我根据MongoDb文档构造了以下查询来执行此操作:
db.item.update({"name":"car"}, {"$push" : {"attributes" : {"color": "red", "qty": 20}}}, upsert=true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
这行得通,我得到了:
db.item.find({"name":"car"}).pretty()
{
"_id" : ObjectId("5c5635194b6929067972b85c"),
"name" : "car",
"attributes" : [
{
"color" : "blue",
"qty" : 10
},
{
"color" : "red",
"qty" : 20
}
]
}
但是,如果再次运行查询,则会添加重复的条目:
db.item.update({"name":"car"}, {"$push" : {"attributes" : {"color": "red", "qty": 20}}}, upsert=true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.item.find({"name":"car"}).pretty()
{
"_id" : ObjectId("5c5635194b6929067972b85c"),
"name" : "car",
"attributes" : [
{
"color" : "blue",
"qty" : 10
},
{
"color" : "red",
"qty" : 20
},
{
"color" : "red",
"qty" : 20
}
]
}
为什么会这样? upsert应该防止这种情况,还是我误解了upsert的功能?
答案 0 :(得分:1)
upsert是更新或插入,如果存在匹配的文档,则将进行更新,否则插入。
如果您已经有一个匹配的文档,那么将完成更新。 $push
不检查重复项,您需要使用$addToSet
如果要避免重复,则需要使用$addToSet
db.item.update(
{"name":"car"},
{"$addToSet" : {"attributes" : {"color": "red", "qty": 20}}},
{upsert:true}
)
第二次更新的结果
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })