2

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);
adam0101
  • 29,096
  • 21
  • 96
  • 174

2 Answers2

2

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."

a p
  • 3,098
  • 2
  • 24
  • 46
  • Both of these methods still result in the error if the array element doesn't exist. My question is how to insert the array itself if it doesn't exist and then the value into that array. – adam0101 Jun 17 '15 at 20:01
  • 1
    Both of these should create the array if it doesn't exist; your problem (now that I can see your edit) looks like it's because you're trying to traverse based on the field *before* it exists. – a p Jun 17 '15 at 20:03
  • OK, that makes sense, but I still don't know how to write it to make it work. – adam0101 Jun 17 '15 at 20:05
  • Sounds like a different question to me. – a p Jun 17 '15 at 20:11
0

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));
Ivan Cipriani
  • 61
  • 1
  • 5