Tim Gim
Tim Gim

Reputation: 174

How to make an integer Id generator?

As it known, mongoDb default driver doesn't support automatic integer Id generation. I spent 2 days for thinking how to implement my own id generator of unique integer values. So, how to make it ?

Upvotes: 10

Views: 15526

Answers (4)

Oscar Foley
Oscar Foley

Reputation: 7025

I would use a GUID as primary key instead of an integer. It has mainly two benefits

  • It is thread safe

  • You don't need to worry about calculating next ID.

  • Code needed to get new ID is pretty easy

    Guid.NewGuid()

Check this useful article in CodingHorror that explains pros and cons of using GUID over classical integer IDs.

Upvotes: 3

Alex
Alex

Reputation: 38529

A late answer, but I thought I'd post this:

https://github.com/alexjamesbrown/MongDBIntIdGenerator

I made a start on an incremental ID generator.
Note - this is far from ideal, and not what mongodb was intended for.

Upvotes: 1

maaz
maaz

Reputation: 4493

Its not good practice to make auto increment Id in MongoDB, as I will hurt in scaling your server, but If you want to make auto increment value it is not advisable to iterate your collection, Instead make a separate table (sequence like concept) and read value from there and increment it using findAndModify. It will be unique per table.

> db.counters.insert({_id: "userId", c: 0});

> var o = db.counters.findAndModify(
...        {query: {_id: "userId"}, update: {$inc: {c: 1}}});
{ "_id" : "userId", "c" : 0 }
> db.mycollection.insert({_id:o.c, stuff:"abc"});

> o = db.counters.findAndModify(
...        {query: {_id: "userId"}, update: {$inc: {c: 1}}});
{ "_id" : "userId", "c" : 1 }
> db.mycollection.insert({_id:o.c, stuff:"another one"});

Upvotes: 7

Tim Gim
Tim Gim

Reputation: 174

Something like that:

public class UniqueIntGenerator : IIdGenerator
{
    private static UniqueIntGenerator _instance;

    public static UniqueIntGenerator Instance { get { return _instance; } }

    static UniqueIntGenerator()
    {
        _instance = new UniqueIntGenerator();
    }

    public object GenerateId(object container, object document)
    {
        var cont = container as MongoCollection;
        if (cont == null)
            return 0;

        var type = cont.Settings.DefaultDocumentType;
        var cursor = cont.FindAllAs(type);
        cursor.SetSortOrder(SortBy.Descending("_id"));
        cursor.Limit = 1;

        foreach (var obj in cursor)
            return GetId(obj) + 1;

        return 1;
    }

    private int GetId(object obj)
    {
        var properties = obj.GetType().GetProperties();
        var idProperty = properties.Single(y => y.GetCustomAttributes(typeof(BsonIdAttribute), false).SingleOrDefault() != null);
        var idValue = (int)idProperty.GetValue(obj, null);
        return idValue;
    }

    public bool IsEmpty(object id)
    {
        return default(int) == (int)id;
    }
}

Upvotes: -4

Related Questions