解释为什么要在重复输入中重复输入

时间:2019-02-03 15:18:40

标签: mongodb

假设我有这个收藏夹:

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的功能?

1 个答案:

答案 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 })