Add element or add to array using MongoDB C# driver 2.0

3.8k views Asked by At

I have a document that can have a "Favorites" element on it and I'm trying to push a new value into an array on that element. However, I'm getting an error because the document I'm trying to update doesn't have the "Favorites" element. How can I create the element if it doesn't exist so I can push the new value into it's array property? Can I do it in one operation? Here's what I'm doing, but I get the error cannot use the part (Favorites of Favorites.ProgramIds) to traverse the element ({Favorites: null})

var filter = Builders<UserEntity>.Filter.Eq(u => u.Id, userId);
var update = isFavorite ? Builders<UserEntity>.Update.AddToSet(u => u.Favorites.ProgramIds, id)
    : Builders<UserEntity>.Update.Pull(u => u.Favorites.ProgramIds, id);
await collection.UpdateOneAsync(filter, update);
2

There are 2 answers

4
a p On

If want duplicates to be ignored, you can use $addToSet, which will create or append into the array, treating it as a set. If you just want it to be a normal-ass normal array, then use $push. If you're explicitly using $push and getting errors, you shouldn't, and that's a separate problem; see the official docs: "If the field is absent in the document to update, $push adds the array field with the value as its element."

0
Ivan Cipriani On

If there are possibilities that the Favorities array can be null you have to create the array before use "addToSet" or "push" otherwise you get the error:

MongoDB.Driver.MongoWriteException: 'A write operation resulted in an error. Cannot apply $addToSet to non-array field. Field named 'Favorites' has non-array type null'

Below an example where if the array is null a new one is set

            var filter = Builders<UserEntity>.Filter.Eq(u => u.Id, userId);
            if (!isTheFavoritesArrayNotNull)
            {
                await collection.UpdateOneAsync(filter,
                    isFavorite ? Builders<UserEntity>.Update.Set(u => u.Favorites, new List<Favorite>()));
            }
            await collection.UpdateOneAsync(filter,
                    Builders<UserEntity>.Update.AddToSet(u => u.Favorites.ProgramIds, id));