2016-03-31 7 views
2

ich eine pymongo Sammlung in Form haben:

{ 
    "_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 
     } 
    ] 
} 

, wenn ich neue Lieferantendaten zu erhalten, wenn der Lieferant ID geändert hat, möchte ich erfassen, dass bis spätestens zum Einstellen das vorherige "neueste" zu False und das $ schieben den neuen Rekord.

$ set nicht funktioniert, wie ich es zu beschäftigen versuche (kommentierten Code nach ‚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}}) 

jede und alle Hilfe wird sehr geschätzt.

Dieser ganze Prozess scheint unnatürlich ausführlich - sollte ich einen rationelleren Ansatz verwenden?

Danke!

Antwort

2

Sie können mit Positionsoperatoren versuchen.

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

wird diese Abfrage supplier_ids.latest = false aktualisieren, wenn es in dem Dokument wahr ist und andere Bedingungen entspricht.

Der Haken ist, dass Sie Feld Array als Teil der Bedingung auch einschließen müssen. Weitere Informationen finden Sie unter Update