I am facing a problem. Using the database myDb and the collection myCollection I inserted the document below

{ "_id": 1, "status": 1, "arrayField": [ { "A": 1, "B": 1 } ] }

I am executing the code in C# to update the status if the status is equal to 1 otherwise, it should remain the same. I am using the code below

var update = new BsonDocument() { ["$set"] = new BsonDocument() { ["status"] = new BsonDocument() { ["$cond"] = new BsonDocument() { ["if"] = new BsonDocument() { ["$eq"] = new BsonArray() { "$status", 1 } }, ["then"] = 30, ["else"] = "$status" } } } }; var filter = Builders<BsonDocument>.Filter.Eq("_id", 1); collection.FindOneAndUpdate(filter, update, new FindOneAndUpdateOptions<BsonDocument, BsonDocument>() { ReturnDocument = ReturnDocument.After });

When I execute this code, instead my code being like:

{ "_id": 1, "status": 30, "arrayField": [ { "A": 1, "B": 1 } ] }

It is like:

{ "_id": 1, "status": { "$cond": { "if": { "$eq": [ "$status", 1 ] }, "then": 30, "else": "$status" } }, "arrayField": [ { "A": 1, "B": 1 } ] }

For some reason that i don’t understand, the MongoDB driver is not recognizing the query operation inside the $set statement and is setting the query as the raw value.

Hi, @Ryan_Brocco,

Welcome to the MongoDB Community Forums. I understand that you are seeing unexpected behaviour when executing a FindOneAndUpdate operation. The root cause is that the update parameter is a BsonDocument rather than a PipelineDefinition.

A BsonDocument says match this document and set the field (status) to the value ($cond document). A PipelineDefinition says run this aggregation pipeline to set the values for the matched document.

Here’s an example of how you can perform the desired update using the .NET/C# Driver.

var update = new [] { new BsonDocument { ["$set"] = new BsonDocument() { ["status"] = new BsonDocument() { ["$cond"] = new BsonDocument() { ["if"] = new BsonDocument() { ["$eq"] = new BsonArray() { "$status", 1 } }, ["then"] = 30, ["else"] = "$status" } } } }}; var pipeline = PipelineDefinition<BsonDocument, BsonDocument>.Create(update); var filter = Builders<BsonDocument>.Filter.Eq("_id", 1); var after = coll.FindOneAndUpdate(filter, pipeline, new FindOneAndUpdateOptions<BsonDocument, BsonDocument>() { ReturnDocument = ReturnDocument.After });

Hope this helps.

Sincerely,
James

Closed 2 days ago

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.