kokeksibir
kokeksibir

Reputation: 1745

In MongoDB, method to keep the previous value of a field in a different field while updating an object?

Say I have an object with field state, I want to update this field, while keeping the previous value of state in previous_state field. First, I have tried to make an update with unset-rename-set:

collection.update(query, {$unset: {previous_state: ""}, $rename: {state: "previous_state"}, $set: {state: value}})

no surprise it did not work. After reading:

I am nearly convinced that I do not have a solution to perform this in a single query. So the question is what is the best practice to do it?

Upvotes: 2

Views: 2945

Answers (2)

marcor92
marcor92

Reputation: 537

There are various ways to do it, depending on the version of MongoDB, and they are described in this answer from another thread: https://stackoverflow.com/a/37280419/5538923 . For MongoDB 3.4+, for example, there is this query that can be put in MongoSH:

db.collection.aggregate(
[
    { "$addFields": { 
        "previous_state": { "$concat": [ "$state" ] },
        "state": { "$concat": [ "$state", " customly modified" ] } 
    }},
    { "$out": "collection" }
])

Also note that this query works only when the MongoDB instance is not sharded. When sharded (e.g., often the case in Microsoft Azure CosmosDB), the method described in that answer for MongoDB 3.2+ works, or alternatively put a new collection as destination (in the $out close), and then import the data in the original collection, after removing all the data there.

Upvotes: 1

Lombric
Lombric

Reputation: 840

One solution (if you've got onlty one writer) could be to trigger your update in two steps:

> var previousvalue = collection.findOne(query).state;
> collection.update(query, {$set: {"previous_state": previousvalue, "state": newstatevalue}});

Upvotes: 0

Related Questions