Insert into nested array in C# MongoDB

2019-07-25 04:28发布

I have the following document in a collection called Users in MongoDB. I am trying to insert a <SpecificBeer> into beersInCellar[] of the mycellar cellar. I've tried all kinds of combinations in the filter and update objects but just can't wrap my head around inserting into a nested array. I know how to find a document and insert things into it, just not into an array in that document.

{
    "_id" : ObjectId("5920751b6d4f6a27cf7985a8"),
    "name" : "FullName",
    "emailAddress" : "emailaddress@example.com",
    "cellars" : [
        {
            "cellarId" : "mycellar",
            "cellarName" : "My Cellar",
            "beersInCellar" : [ ]
        }
    ]
}

SpecificBeer model:

public class SpecificBeer
        {
            public string ourid 
            { 
                get
                {
                    return ID.ToString();
                } 
                set
                { 
                    ID = ObjectId.Parse(value); 
                }
            }
            [BsonId]
            private ObjectId ID {get; set;}
            public string year { get; set; }
            public string variant { get; set; }
            public string quantity { get; set; }
            public string numberForTrade { get; set; }
        }

Insert method

public async Task<SpecificBeer> AddBeerToList(string id, SpecificBeer specificBeer, string cellarId)
{
        var filter = Builders<User>.Filter.Eq(e => e.userId, id) & Builders<User>.Filter.Eq(e => e.cellars, cellarId);

        var update = Builders<Cellar>.Update.Push<SpecificBeer>(e => e.beersInCellar, specificBeer);

        await _collection.FindOneAndUpdateAsync(filter, update);
        return specificBeer;
}

1条回答
劳资没心,怎么记你
2楼-- · 2019-07-25 04:58

You have to use $positional operator.

You've to include the field(cellarId) from the cellars for mongoDB to locate the index of element and replace the placeholder($) with the found index from query part in the update part to push the element in beersInCellar.

Something like

 var filter = Builders<User>.Filter.Eq(e => e.name, "FullName") & Builders<User>.Filter.ElemMatch(e => e.cellars, Builders<Cellar>.Filter.Eq(e => e.cellarId, "mycellar"));
 var update = Builders<User>.Update.Push(e => e.cellars[-1].beersInCellar, specificBeer);

Shell Query for reference:

db.collection.update({"name" : "FullName", "cellars":{$elemMatch:{"cellarId":"mycellar"}}},{$push:{"cellars.$.beersInCellar":{"quantity":1, "year":1986}}})

MongoDB doesn't have first class support for updating fields ( for example quantity ) in the nesting arrays inside arrays.

You can track the jira which is going to allow multiple level updates.

https://jira.mongodb.org/browse/SERVER-27089

You may want to revisit your structure for now. Try promoting the beersInCellar arrays to top level.

查看更多
登录 后发表回答