$ pu sh и $ set в одном запросе на обновление с условием $ cond pymon go mongodb - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь обновить свою коллекцию

Для одиночного объекта необходимо обновить статус и время обновления.

Введите идентификатор объекта как id новый статус как текущий status

Условие Если new status отличается от status в БД, тогда необходимо $push new status и timestamp в массив activity_log. И обновите обновление updated_time и status записи.

Если new status и предыдущий статус совпадают, то updated_time будет обновлено.

Возможно ли сделать это в pymon go с помощью одного обновления?

collection.update({
        '_id': ObjectId(id),
    }, {
        '$cond': {
            'if': {
                'status': {
                    '$ne': current_status
                }
            },
            'then': {
                '$push': {
                    'activity_log': {
                        'status': current_status,
                        'changed_time': datetime.now()
                    }
                }
            },
            'else': None
        },
        '$set': {
            'status': current_status,
            'updated_time': datetime.now()
        }
    })

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Оператор $cond не является управлением потоком, как if-then-else, это выражение, которое возвращает значение.

Если вы хотите условно обновить поле на основе значения другого поля в того же документа вы можете использовать конвейерную форму обновления, присвоив полю результат выражения $cond.

collection.update(
     {'_id': ObjectId(id)}, 
     [{'$set': {
            'status': current_status,
            'updated_time': datetime.now(),
            'activity_log':{
              '$cond': {
                'if': {'$ne': ['$status',current_status]}
                'then': {$concatArrays:['$activity_log',[
                          {
                           'status': current_status,
                           'changed_time': datetime.now()
                          }
                ]]},
                'else': '$activity_log'
            }
      }}]
)
1 голос
/ 08 мая 2020

Вы можете сделать это в одном запросе, запрос обновления из MongoDB 4.2 поддерживает конвейер агрегации , вы можете сделать это в соответствии с приведенным ниже кодом

collection.update(
     {'_id': ObjectId(id)}, 
     [{'$set': {
            'status': current_status,
            'updated_time': datetime.now(),
            'activity_log':{
              '$cond': {
                'if': {'$ne': ['$status',current_status]},
                'then': {$concatArrays:['$activity_log',[
                          {
                           'status': current_status,
                           'changed_time': datetime.now()
                          }
                ]]},
                'else': '$activity_log'
            }
      }}}]
)
...