Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB .NET not generating _id on upsert

I'm attempting to upsert a document into MongoDB 2.4.4 using the .NET driver. It seems not to automatically generate the _id on upserts, though it does correctly generate the _id on plain inserts. How can I cause the driver to properly generate the _id?

Here is a small example that demonstrates the problem.

public class MongoObject
{
    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))]
    [BsonRepresentation(BsonType.ObjectId)]
    public string MongoID { get; set; }

    public int Index { get; set; }
}

var obj = new MongoObject()
{
    Index = 1
};

//This inserts the document, but with a _id set to Null
_collection.Update(Query.EQ("Index", BsonValue.Create(1)), Update.Replace(obj), UpdateFlags.Upsert, new WriteConcern() { Journal = true });

//This inserts the document with the expected autogenerated _id
//_collection.Insert(obj);
like image 947
Brian Reischl Avatar asked Nov 26 '13 17:11

Brian Reischl


People also ask

Does MongoDB support Upsert?

Here in MongoDB, the upsert option is a Boolean value. Suppose the value is true and the documents match the specified query filter. In that case, the applied update operation will update the documents. If the value is true and no documents match the condition, this option inserts a new document into the collection.

Is MongoDB Upsert Atomic?

Upsert is not atomic.

Is Upsert false by default?

By default, the value of the upsert option is false. If the value of upsert in a sharded collection is true then you have to include the full shard key in the filter.

Is there an Upsert option in the MongoDB insert command?

Since upsert is defined as operation that "creates a new document when no document matches the query criteria" there is no place for upserts in insert command. It is an option for the update command.


1 Answers

And of course I find the answer immediately after posting the question. From this answer, the solution is to add a [BsonIgnoreIfDefault] attribute to the ID. In the example from the question it would be:

public class MongoObject
{
    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))]
    [BsonRepresentation(BsonType.ObjectId)]
    [BsonIgnoreIfDefault]    // <--- this is what was missing
    public string MongoID { get; set; }

    public int Index { get; set; }
}
like image 58
Brian Reischl Avatar answered Sep 24 '22 16:09

Brian Reischl