skip to Main Content

I only find questions about the other way around. But in my case I need to update a subdocument auditInfo which might or might not exist. In case it does not exist, it should be ignored. But using the $set operator would create the field in this case.

If it does exist, then I’d like to update it using $set to update single fields of the subdocument.

So far I haven’t found any solution to this. Moreover I’m using a combined update definition for the whole document, so this way it is not possible to execute another updateOne with a filter on the field. The only way would either be an operator that does it automatically or maybe some array filter magic (but since the subdocument is at the root of the document I guess array filters won’t work here).

This is my document:

{
  "_id": {
    "$oid": "6409b3bdaa5da4b2cecb2fda"
  },
  "Version": 1,
  "auditInfo": {
    "Version": 1,
    "creationTimestamp": {
      "$date": {
        "$numberLong": "-62135596800000"
      }
    },
    "changeTimestamp": {
      "$date": {
        "$numberLong": "1678359412574"
      }
    },
    "creationUser": {
      "$binary": {
        "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
        "subType": "04"
      }
    },
    "changeUser": {
      "$binary": {
        "base64": "KIvTths/Q1GsbEp1L04axA==",
        "subType": "04"
      }
    }
  },
  "dataFieldContainerId": {
    "$binary": {
      "base64": "RFv0FiWNQOi5Ei9ZBlU/OA==",
      "subType": "04"
    }
  },
  "dataFields": [
    ...
  ]
}

I need to update changeTimestamp and changeUser if the subdocument auditInfo exists.

2

Answers


  1. You can use an aggregation between $cond and $exists.
    check with a $cond statement if the auditInfo exists then execute your query.
    you can find how to use it here :
    https://www.mongodb.com/docs/manual/reference/operator/aggregation/cond/

    Login or Signup to reply.
  2. If I’ve understood correctly you can use $exists into find object to update only values where auditInfo exists.

    So I think you are looking for this query

    And can be translated into c# code into something like this (not tested):

    var filter = Builders<BsonDocument>.Filter.And(
        Builders<BsonDocument>.Filter.Eq("_id", new ObjectId("6409b3bdaa5da4b2cecb2fda")),
        Builders<BsonDocument>.Filter.Exists("auditInfo")
    );
    
    var update = Builders<BsonDocument>.Update.Set("auditInfo.changeTimestamp", DateTime.Now)
                                              .Set("auditInfo.changeUser", yourUser);
    
    var result = await collection.UpdateOneAsync(filter, update);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search