Insert element into nested array in Mongodb

淺唱寂寞╮ 提交于 2019-11-30 19:46:13

You can do this using FindOneAndUpdateAsync and positional operator

public async Task Add(string productId, string categoryId, SubCategory newSubCategory)
{
    var filter = Builders<Product>.Filter.And(
         Builders<Product>.Filter.Where(x => x.Id == productId), 
         Builders<Product>.Filter.Eq("Categories.Id", categoryId));
    var update = Builders<Product>.Update.Push("Categories.$.SubCategories", newSubCategory);
    await collection.FindOneAndUpdateAsync(filter, update);
}

Adding an example for my case. Did work but without the dollar sign when entering inside an array:

public async Task AddCustomMetadata()
       {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("EntityCustomMetadataFieldId", "5bf81296-feda-6447-b45a-08d5cb91211c");
            var filter = Builders<BsonDocument>.Filter.Eq("_id", "6c7bb4a5-d7cc-4a8d-aa92-b0c89ea0f7fe");
            var update = Builders<BsonDocument>.Update.Push("CustomMetadata.Fields", dic);
            await _context.BsonAssets.FindOneAndUpdateAsync(filter, update);
        }

You can use the positional operator using Linq expressions too:

public async Task Add(string productId, string categoryId, SubCategory newSubCategory)
{
    var filter = Builders<Product>.Filter.And(
         Builders<Product>.Filter.Where(x => x.Id == productId), 
         Builders<Product>.Filter.ElemMatch(x => x.Categories, c => c.Id == categoryId));
    var update = Builders<Product>.Update.Push(x => x.Categories[-1].SubCategories, newSubCategory);
    await collection.FindOneAndUpdateAsync(filter, update);
}

And get yourself free of using hard-coded property names inside strings.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!