1

I have a document like this

{
"_id": "63dafa72f21d48312d8ca405",
"tasks": [{
    "_ref": "63d8d8d01beb0b606314e322",
    "data": {
        "values": [{
            "key": "Deadline",
            "value": "2014-10-13"
        }]
    }
}, {
    "_ref": "84dd046c6695e32322d842f5",
    "data": {
        "values": []
    }
}]
}

Now I want to update the value inside values which is inside data if the _ref field do match my input.

My code so far:

public bool updateProject(Project dbPro, Project pro)
{
    var collection = db.GetCollection<BsonDocument>("projects");
    var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse( dbPro.Id));
    var update = Builders<BsonDocument>.Update.AddToSetEach("tasks", pro.Tasks);
    var result = collection.UpdateOne(filter, update);
    if (result.IsModifiedCountAvailable)
    {
        if (result.ModifiedCount == 1)
        {
            return true;
         }
    }
    return false;
}

At the moment this code does only append the documents as new tasks instead to append the values to the matching tasks. Maybe someone has an idea how to achieve this behavior?

UPDATE

I tried it like @Shane Oborn said. But its still not working for me.

            var collection = db.GetCollection<BsonDocument>("projects");
        var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse( dbPro.Id));
        var update = Builders<BsonDocument>.Update.Push("tags", buildBsonArrayFromTags(pro.Tags));
        var result = collection.UpdateOne(filter, update);
        if (result.IsModifiedCountAvailable)
        {
            if (result.ModifiedCount == 1)
            {
                return true;
            }

        }


        return false;
    }

Instead to override the data it appends an array to my array.

enter image description here

UPDATE

OK instead of push i did need set. And it worked then.

2
  • 1
    Take a look at this question, It could help you. Commented Jan 19, 2017 at 13:50
  • Thanks. I will try it. Commented Jan 19, 2017 at 13:57

1 Answer 1

2

I don't have the exact code accessible, but close. I have a method that performs "upserts" (which "adds" if new, or "updates" if existing). This should get you close:

// The variable "doc" below is a BsonDocument

var updateRequests = new List<WriteModel<BsonDocument>>();
updateRequests.Add(new ReplaceOneModel<BsonDocument>(
    CreateBsonDocumentFilterDefinition(filterKeyName, filterKeyValue), doc)
    {
        IsUpsert = true
    });
var writeResult = await collection.BulkWriteAsync(updateRequests);

The key objects here for you are "ReplaceOneModel" and the "IsUpsert" property for the filter definition.

Good luck!

UPDATE:

Another method I have that does updates in subdocuments looks like this:

// Below, "subDocument" is a BsonDocument, and "subDocArrayName" is a string
// that should match the name of the array that contains your sub-document
// that will be updated.

var collection = _database.GetCollection<BsonDocument>(collectionName);

var builder = Builders<BsonDocument>.Update;
var update = builder.Push(subDocArrayName, subDocument);

await collection.UpdateOneAsync(CreateBsonDocumentFilterDefinition(filterKeyName, filterKeyValue), update);
Sign up to request clarification or add additional context in comments.

3 Comments

I will give this a try too. Thanks for the fast help.
I tried your methods but it didn't work. I updated my post
OK i figured it now. Instead of push i used set. And it worked

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.