2

I have a data model that's structured something like this:

{
    "_id": "1234abcd",
    "name": "The Stanley Parable"
    "notes": [
        {
            "_id": "5678efgh",
            "content": "Kind of a walking simulator."
        },
                    {
            "_id": "5678efgh",
            "content": "Super trippy."
        },
    ]
}

I'm using the mongo driver for C# to interact with this model in .NET Core. I'm trying to add a new note to a particular game -- without necessarily being sure that there are any notes on that game already. This is what I've been able to find for adding to a nested list:

var filter = Builders<Mongo_VideoGame>.Filter.Eq("Id", id);
var update = Builders<Mongo_VideoGame>.Update.Push<Mongo_Note>(v => v.Notes, mongoNote);

var editedGame = _context.VideoGames.FindOneAndUpdate(filter, update);

But my problem is that this only works if there's already a "notes" element on the game model. I could just add an empty array when I make the original game, but that seems less flexible to changing the schema (i.e. what if I was adding notes to existing data).

An exception of type 'MongoDB.Driver.MongoCommandException' occurred in MongoDB.Driver.Core.dll but was not handled in user code: 'Command findAndModify failed: The field 'notes' must be an array but is of type null in document'

1 Answer 1

1

So I ended up finding a solution to this.

First off, .Push() does work as I originally expected. It will create an array if one doesn't already exist.

My actual problem had to do with the C# Model I was using. Previously:

public class Mongo_VideoGame
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    [BsonElement("name")]
    public string Name { get; set; }

    [BsonElement("notes")]
    public List<Mongo_Note> Notes { get; set; }

}

But since there was no notes on the document it found, I was basically trying to insert into a null notes array. So to fix this, I set the default value for Notes so that it could be pushed into. Like this:

public class Mongo_VideoGame
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    [BsonElement("name")]
    public string Name { get; set; }

    [BsonElement("notes")]
    public List<Mongo_Note> Notes { get; set; } = new List<Mongo_Note>();

}

Both the case of adding to an existing array and creating the array if it does not exist work now.

Sign up to request clarification or add additional context in comments.

1 Comment

defining the storage does not allocate the storage as you discovered. when using a DI container the hardwired new list would need to be moved. Perhaps to the constructor as constructor based injection is fairly common.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.