MongoDB聚合更新嵌套数组对象时如何正确获取当前文档字段值
The issue with your current code is that '$specs.name' refers to the name field of each element in the top-level specs array, not the name of the individual models entry you're modifying. To target the current model's name, you need to use nested $map stages to iterate through both the specs and models arrays, and reference the inner model variable within the valid subdocument.
Corrected C# Aggregation Code
var addNewFieldsDefinition = new BsonDocument { { "$addFields", new BsonDocument { { "specs", new BsonDocument { { "$map", new BsonDocument { { "input", "$specs" }, { "as", "spec" }, { "in", new BsonDocument { { "name", "$$spec.name" }, { "models", new BsonDocument { { "$map", new BsonDocument { { "input", "$$spec.models" }, { "as", "model" }, { "in", new BsonDocument { { "$mergeObjects", new BsonArray { // Omit the original "name" field from the model new BsonDocument("$omit", new BsonArray { "$$model", "name" }), // Add the new "valid" subdocument using the current model's name new BsonDocument { { "valid", new BsonDocument { { "isValid", true }, { "currentName", new BsonArray { "$$model.name" } } } } } } } } } } } } } } } } } } } } } }; var t1 = collection .Aggregate() .Match(filterDefinition) .AppendStage<BsonDocument>(addNewFieldsDefinition) .Merge(collection);
Key Changes Explained
Nested
$mapStages:- The outer
$mapiterates over each element in thespecsarray (using the variable$$spec). - The inner
$mapiterates over each model in the current spec'smodelsarray (using the variable$$model).
- The outer
Referencing the Current Model's Name:
$$model.namedirectly references the name of the individual model entry being processed, which is exactly what you need forcurrentName.
Removing the Original
nameField:$omitremoves the originalnamefield from the model document, while preserving all other existing fields (likecategories).
Merging Fields:
$mergeObjectscombines the modified model (without the name field) with the newvalidsubdocument, creating the desired structure for each model entry.
After running this aggregation, each models entry will have the valid subdocument with isValid: true and currentName set to the original model's name, and the original name field will be removed.
内容的提问来源于stack exchange,提问作者DreadAngel

