使用特定查询更新的更好方法

时间:2017-06-17 04:10:06

标签: mongodb pymongo

以下是这种情况:我想更新具有特定ID的文档,并且其update_time早于较新版本,如果找不到这样的文档,请使用较新的文档创建文档。

我的第一个解决方案是:

db.collection.update(
  {
    '_id': 'the_specific_id',
    'update_time': {'$lt': new_date_time}
  },
  {
     '$set' :{
        'field_1': 'value_1',
        'field_2': 'value_2',
        'update_time': new_data_time
     }

  },
  {  'upsert': true}
)

在此解决方案中,如果找到doc,则更新很好。如果由于找不到“_id”而找不到doc,则upsert很好。但是,如果找不到doc因为db中的doc具有较新的'update_time',则后续upsert不正确(因为主键重复)。

所以我必须最终得到这个(psudo代码):

try:
   db.collection.insert({
    '_id': 'the_specific_id',
    'field1': 'value1',
    'field2': 'value2',
    'update_time': new_date_time
  })
except Exception as e:
   if e.message.find('duplication'):
       db.collection.update(
        {
         '_id': 'the_specific_id',
         'update_time': {'$lt': new_date_time}
        },
        {
          '$set' : {
             'field_1': 'value_1',
             'field_2': 'value_2',
             'update_time': new_data_time
           }
        },
        {  'upsert': false})

这看起来很复杂。我想知道这个解决方案有没有更好的方法?

3 个答案:

答案 0 :(得分:0)

您可以先限制搜索,只查找更新时间小于新更新时间的项目。一旦满足这些选择,您就可以像以前一样使用upsert。

  db.collection.update(
  {
    '_id': 'the_specific_id',
    'update_time': {'$lt': new_date_time}
  },
  {
    'field_1': 'value_1',
    'field_2': 'value_2',
    'update_time': new_date_time
  },
  {  'upsert': true}
)

答案 1 :(得分:0)

您可以使用用于承诺的findOrCreate,但这也包括{upsert:true}语句,它可以帮助您更新,创建机制。

感谢。

答案 2 :(得分:0)

正如@Neil Lunn所指出的,最简单的方法是:

try: 
  db.collection.update(
  {
    '_id': 'the_specific_id',
    'update_time': {'$lt': new_date_time}
  },
  {
   '$set' :{
    'field_1': 'value_1',
    'field_2': 'value_2',
    'update_time': new_data_time }
  },
  {'upsert': true})
except DuplicateKeyError as e:
  pass