обновление многих объектов по ссылке на объекты в тех же документах

#python #mongodb #pymongo

#python #mongodb #pymongo

Вопрос:

Допустим, у меня есть коллекция, подобная следующей. Для каждого содержащегося документа animals.horse я хочу установить animals.goat значение равно animals.horse (чтобы лошади не были одинокими или в меньшинстве).

 [
  {
    "_id": 1,
    "animals": {
      "goat": 1
    }
  },
  {
    "_id": 2,
    "animals": {
      "cow": 1,
      "horse": 2,
      "goat": 1
    }
  },
  {
    "_id": 3,
    "animals": {
      "horse": 5
    }
  },
  {
    "_id": 4,
    "animals": {
      "cow": 1
    }
  }
]
 

В оболочке Mongo это работает по желанию:

 db.collection.update(
   {"animals.horse": { "$gt": 0 }},
   [ { "$set": { "animals.goat": "$animals.horse" } } ],
   { "multi": true }
)
 

что позволяет достичь желаемого результата:

 [
  {
    "_id": 1,
    "animals": {
      "goat": 1
    }
  },
  {
    "_id": 2,
    "animals": {
      "cow": 1,
      "goat": 2,
      "horse": 2
    }
  },
  {
    "_id": 3,
    "animals": {
      "goat": 5,
      "horse": 5
    }
  },
  {
    "_id": 4,
    "animals": {
      "cow": 1
    }
  }
]
 

Однако в pymongo это не работает — коллекция не изменяется.

 db.collection.update_many( filter = {'animals.horse': {'$gt':0} },  
                           update = [ {'$set': {'animals.goat': '$animals.horse' } } ],
                           upsert = True
                        )
 

Что я делаю не так?

Комментарии:

1. В примере pymongo есть лишний двоеточие? ваш фильтр имеет {‘horse’: {‘$ gt’ : : 0}} . Разве это не должно быть {‘$ gt’: 0}?

2. Спасибо @CrunchyLentils это была просто опечатка в моем примере, но не в моем реальном коде.

3. Попробуйте установить slowms равным 0 в mongod. Это заставит его регистрировать все запросы, чтобы вы могли точно проверить, какую операцию этот код отправил в базу данных.