Why does upsert a record using update_one raise ValueError?
Question:
I want to add a record to the collection if the key doesn’t already exist. I understand [MongoDB][1] offers the upsert
for this so I did a
db.collection.update({"_id":"key1"},{"_id":"key1"},True)
This seems to work.
However in the Pymongo documentation it says that update is deprecated and use to update_one()
.
But:
db.collection.update_one({"_id":"key1"},{"_id":"key1"},True)
Gives:
raise ValueError('update only works with $ operators')
ValueError: update only works with $ operators
I don’t really understand why update_one
is different and why I need to use a $
operator. Can anyone help?
Answers:
This is because you didn’t specify any update operator.
For example to $set
the id
value use:
db.collection.update_one({"_id":"key1"}, {"$set": {"id":"key1"}}, upsert=True)
Note that in the Mongo shell, this will simply replace the document with the new document.
Use replace_one()
instead of update_one()
. the 3rd parameter of replace_one()
is upsert
, too.
db.collection.replace_one({"_id": "key1"}, {"_id": "key1"}, True)
My personal opinion is this implementation of update_one()
is inconsistent with the behaviour of MongoDB client. The upsert
option in update_one()
is actually meaningless. But the developers of pyMongo may just want to use this to distinguish update_one()
and replace_one()
.
I want to add a record to the collection if the key doesn’t already exist. I understand [MongoDB][1] offers the upsert
for this so I did a
db.collection.update({"_id":"key1"},{"_id":"key1"},True)
This seems to work.
However in the Pymongo documentation it says that update is deprecated and use to update_one()
.
But:
db.collection.update_one({"_id":"key1"},{"_id":"key1"},True)
Gives:
raise ValueError('update only works with $ operators')
ValueError: update only works with $ operators
I don’t really understand why update_one
is different and why I need to use a $
operator. Can anyone help?
This is because you didn’t specify any update operator.
For example to $set
the id
value use:
db.collection.update_one({"_id":"key1"}, {"$set": {"id":"key1"}}, upsert=True)
Note that in the Mongo shell, this will simply replace the document with the new document.
Use replace_one()
instead of update_one()
. the 3rd parameter of replace_one()
is upsert
, too.
db.collection.replace_one({"_id": "key1"}, {"_id": "key1"}, True)
My personal opinion is this implementation of update_one()
is inconsistent with the behaviour of MongoDB client. The upsert
option in update_one()
is actually meaningless. But the developers of pyMongo may just want to use this to distinguish update_one()
and replace_one()
.