MrDuk
MrDuk

Reputation: 18242

pymongo update_one(), upsert=True without using $ operators

I have documents in the form:

{"hostname": "myhost1.com", "services": { ... } }

What I'd like to do is the following:

dataset = requests.get('http://endpoint.com/hardware.json').json()
for hostname, services in dataset[0].items():
    db.titleHardware.update_one({'hostname':hostname},
                                {services.keys()[0]: services.values()[0]}, 
                                True) #upsert

However, I'm getting the following error:

ValueError: update only works with $ operators

Is there a way to accomplish this update of the entire "services" chunk, based on the "hostname" key (and ultimately, inserting a new document if hostname doesn't exist)? I know I can write logic to compare what's in my MongoDB with what I'm trying to update/insert, but I was hopeful that there may be something already in pymongo or something that I could use for this.

Upvotes: 13

Views: 31858

Answers (2)

sroecker
sroecker

Reputation: 615

Did you look at the mongodb documentation for updateOne? You have to specify an update operator such as $set:

for hostname, services in dataset[0].items():
    db.titleHardware.update_one({'hostname':hostname},
                                {'$set': {services.keys()[0]: services.values()[0]}}, 
                                upsert=True)

Upvotes: 15

A. Jesse Jiryu Davis
A. Jesse Jiryu Davis

Reputation: 24009

Use replace_one to replace documents.

for hostname, services in dataset[0].items():
    db.titleHardware.replace_one({'hostname':hostname},
                                 {'hostname':hostname,
                                  services.keys()[0]: services.values()[0]}, 
                                 True)

Upvotes: 12

Related Questions