2

I have a pymongo collection in the form of:

{
    "_id" : "R_123456789",
    "supplier_ids" : [
        {
                "id" : "S_987654321",
                "file_version" : ISODate("2016-03-15T00:00:00Z"),
                "latest" : false
        },
        {
                "id" : "S_101010101",
                "file_version" : ISODate("2016-03-29T00:00:00Z"),
                "latest" : true
        }
    ]
}

when I get new supplier data, if the supplier ID has changed, I want to capture that by setting latest on the previous 'latest' to False and the $push the new record.

$set is not working as I am trying to employ it (commented code after 'else'):

import pymongo
from dateutil.parser import parse

new_id = 'S_323232323'
new_date = parse('20160331')

with pymongo.MongoClient() as client:
    db = client.transactions
    collection_ids = db.ids

    try:
        collection_ids.insert_one({"_id": "R_123456789",
                                   "supplier_ids": ({"id": "S_987654321",
                                                     "file_version": parse('20160315'),
                                                     "latest": False},
                                                    {"id": "S_101010101",
                                                     "file_version": parse('20160329'),
                                                     "latest": True})})
    except pymongo.errors.DuplicateKeyError:
        print('record already exists')

    record = collection_ids.find_one({'_id':'R_123456789'})

    for supplier_id in record['supplier_ids']:
        print(supplier_id)
        if supplier_id['latest']:
            print(supplier_id['id'], 'is the latest')

            if supplier_id['id'] == new_id:
                print(new_id, ' is already the latest version')
            else:
                # print('setting', supplier_id['id'], 'latest flag to False')
                # <<< THIS FAILS >>>
                # collection_ids.update_one({'_id':record['_id']},
                #                           {'$set':{'supplier_ids.latest':False}})
                print('appending', new_id)
                data_to_append = {"id" : new_id,
                                  "file_version": new_date,
                                  "latest": True}
                collection_ids.update_one({'_id':record['_id']},
                                          {'$push':{'supplier_ids':data_to_append}})

any and all help is much appreciated.

This whole process seems unnaturally verbose - should I be using a more streamlined approach?

Thanks!

1 Answer 1

2

You can try with positional operators.

collection_ids.update_one(
    {'_id':record['_id'], "supplier_ids.latest": true},
    {'$set':{'supplier_ids.$.latest': false}}
)

This query will update supplier_ids.latest = false, if it's true in document and matches other conditions.

The catch is you have to include field array as part of condition too.

For more information see Update

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.