ST NS
ST NS

Reputation: 21

Increment sub document field in a MongoDb Database

I have this model:

{
    id: long,
    items: [{
        itemId: long,
        amount: decimal
    }]
 }

edit: I need to increment the amount value depending on id and itemId.

My query:

var query = Builders<model>.Filter.And(
    Builders<model>.Filter.Eq(_ => _.id, xxx),
    Builders<model>.Filter.ElemMatch(_ => _.items, _ => _.itemId == yyy)
);

var update = Builders<modelItem>.Update.Inc(_ => _.amount, incrementalAmount);

But i don't know how to execute the query/update.

this.Collection.FindOneAndUpdate(query, update);

Of course i can't use this UpdateDefinition because i must use builder<'model> instead of builder<'modelItem>, but how to increment the sub property ?

Upvotes: 1

Views: 591

Answers (2)

ST NS
ST NS

Reputation: 21

I finally found how to increment the sub document:

The query stay the same, and i use the operator $ to update the appropriate array item:

Builders<Model>.Update.Inc("Items.$.Amount", incrementValue);

For a little bit more complicated increment, Im using the arrayfilter:

var caf = new BsonDocumentArrayFilterDefinition<ModelItem>(new MongoDB.Bson.BsonDocument("caf.ItemId", new MongoDB.Bson.BsonDocument("$eq", YYYY)));
var oaf = new BsonDocumentArrayFilterDefinition<ModelItem>(new MongoDB.Bson.BsonDocument("oaf.ItemId", new MongoDB.Bson.BsonDocument("$ne", YYYY)));

var query = Builders<Model>.Filter.Eq(_ => _.Id, XXXX);

var update = Builders<Model>.Update.Combine(
    Builders<Model>.Update.Inc("Items.$[caf].Amount", incrementValue),
    Builders<Model>.Update.Inc("Items.$[oaf].Amount", -incrementValue)
);

await this.Collection.UpdateManyAsync(query, update, new UpdateOptions()
{
    ArrayFilters = new List<ArrayFilterDefinition>() { caf, oaf}
});

Upvotes: 1

pieperu
pieperu

Reputation: 2772

Just perform an update

var query = Builders<model>.Filter.And(
    Builders<model>.Filter.Eq(_ => _.id, xxx),
    Builders<model>.Filter.ElemMatch(_ => _.items, _ => _.itemId == yyy)
);

var update = Builders<model>.Update.Inc(_ => _.amount, incrementalAmount);

And then to perform the update:

this.Collection.Update(query, update);

Upvotes: 1

Related Questions