Kelly Selden
Kelly Selden

Reputation: 1276

MongoDB C# Driver and server generated ObjectIds

Is there a way get server generated ObjectIds instead of C# Driver generated ObjectIds? Using MongoCollectionSettings.AssignIdOnInsert = false only gets you zeroed out ObjectIds. I'm doing multi-threaded inserts on a capped collection, and I'm seeing threads switch between the ObjectId generation and the insert. This causes out of order ObjectIds in a collection that's supposed to be ordered for tailed cursors sorting on natural order. Right now I'm using a static lock object for the inserts, but that won't help with different executables/servers.

It appears this is possible with the pymongo driver: ObjectID generated by server on pymongo

Upvotes: 1

Views: 1368

Answers (1)

Stennie
Stennie

Reputation: 65403

Getting documents in insertion order from a capped collection

Capped collections maintain documents in insertion order, so you should ideally use natural order rather than relying on the timestamp in the generated _id. Your tailable cursor will be reading documents in natural order, so should not make any assumptions based on the _id.

Generating server-side _id

To generate _id on the server side using the C# driver you need to:

  • set the class attribute [BsonIgnoreIfDefault]
  • set the collection attribute AssignIdOnInsert = false
  • insert a document without an _id

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Bson.Serialization.Attributes;

public class MyDoc {
    [BsonIgnoreIfDefault]
    public ObjectId? Id;
    public int X;
}

public static class Program {
    public static void Main(string[] args) {
        MongoClient client = new MongoClient(); // connect to localhost
        var server = client.GetServer ();
        var database = server.GetDatabase("test");
        var collectionSettings = new MongoCollectionSettings { AssignIdOnInsert = false };
        var collection = database.GetCollection<MyDoc>("nullid", collectionSettings);

        // Insert document without _id
        collection.Insert(new MyDoc { X = 1});
    }
}

Upvotes: 3

Related Questions