Reputation: 77
The goal: to increment double nested field with the specific identifier in the entity.
The example of the document here:
competition_dota2
{
"id" : "b350c9fd-3632-4b0a-b5cb-66e41d530f55",
"type" : "COMPETITION_TYPE_ESPORTDOTA2",
"status_type" : "COMPETITION_STATUS_TYPE_WAITING",
"start_time" :
{
"seconds": "60",
"nanos": 928852400
},
"coefficient_groups" :
[
{
"id" : "b350c9fd-3632-4b0a-b5cb-66e41d530f55",
"name" : "winner",
"type" : "OUTCOME_GROUP_TYPE_ONE_WINNER",
"coefficients" :
[
{
"id" : "b350c9fd-3632-4b0a-b5cb-66e41d530f55",
"description" : "team1 won",
"rate" : 1.2,
"status_type" : "COEFFICIENT_STATUS_TYPE_ACTIVE",
"amount" : 0,
"probability" : 50
},
{
"id" : "3c203bd7-2d7e-4937-a82a-e451cedf2ba8",
"description" : "team2 won",
"rate" : 0,
"status_type" : "COEFFICIENT_STATUS_TYPE_ACTIVE",
"amount" : 0,
"probability" : 50
}
]
}
],
"team1_id" : "b350c9fd-3632-4b0a-b5cb-66e41d530f55",
"team2_id" : "b350c9fd-3632-4b0a-b5cb-66e41d530f55",
"team1_kill_amount" : 0,
"team2_kill_amount" : 0,
"total_time" :
{
"seconds": "60",
"nanos": 928852400
}
}
I'm trying to increment the "Amount" field.
For that, I'm using specific identifiers for both nested fields.
Is it enough to create find option for the top model only?
var competitionIdstring = competitionId.ToString();
var сoefficientIdstring = сoefficientId.ToString();
var filterBuilder = Builders<CompetitionDota2Entity>.Filter;
var updateBuilder = Builders<CompetitionDota2Entity>.Update;
var filterCompetitionId = filterBuilder.Eq(x => x.Id, competitionId.ToString());
var update = Builders<CompetitionDota2Entity>.Update;
var incAmount = update.Inc(
"CompetitionDota2Entity.CoefficientGroups.$.Coefficients.$.Amount",
amount);
var existingCoefficientGroup = await _collection.FindOneAndUpdateAsync(
filterCompetitionId,
incAmount,
_defaultCompetitionDota2EntityFindOption,
token);
Upvotes: 1
Views: 211
Reputation: 51295
You need to works with the update with $[<identifier>]
filtered positional operator in order to update the element in the nested arrays.
With MongoDB .NET Driver v2.16 and above
In MongoDB .NET Driver v2.16 release, it offers the feature of Implement positional update operators in LINQ3.
Pre-requisites:
Enable LinqProvider.V3
in MongoClientSettings
.
MongoClientSettings settings = MongoClientSettings.FromConnectionString(
mongoUri
);
settings.LinqProvider = MongoDB.Driver.Linq.LinqProvider.V3;
var update = Builders<CompetitionDota2Entity>.Update;
var incAmount = update.Inc(x => x.CoefficientGroups.AllMatchingElements("cg")
.Coefficients.AllMatchingElements("c").Amount,
amount);
FindOneAndUpdateOptions<CompetitionDota2Entity> _defaultCompetitionDota2EntityFindOption = new FindOneAndUpdateOptions<CompetitionDota2Entity>
{
ArrayFilters = new ArrayFilterDefinition[]
{
new BsonDocumentArrayFilterDefinition<CoefficientGroup>
(
new BsonDocument("cg._id", competitionIdstring)
),
new BsonDocumentArrayFilterDefinition<Coefficient>
(
new BsonDocument("c._id", сoefficientIdstring)
)
}
};
var existingCoefficientGroup = await _collection.FindOneAndUpdateAsync(
filterCompetitionId,
incAmount,
_defaultCompetitionDota2EntityFindOption,
token);
With MongoDB .NET Driver v2.16 before
var incAmount = update.Inc(
"coefficient_groups.$[cg].coefficients.$[c].amount",
amount);
FindOneAndUpdateOptions<CompetitionDota2Entity> _defaultCompetitionDota2EntityFindOption = new FindOneAndUpdateOptions<CompetitionDota2Entity>
{
ArrayFilters = new ArrayFilterDefinition[]
{
new BsonDocumentArrayFilterDefinition<CoefficientGroup>
(
new BsonDocument("cg._id", competitionIdstring)
),
new BsonDocumentArrayFilterDefinition<Coefficient>
(
new BsonDocument("c._id", сoefficientIdstring)
)
}
};
Demo
Upvotes: 1