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;
}
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.