1

I'm relatively new to MongoDB and just wanting to know how to effectively use Guids as Ids for entities in MongoDB. I've marked my Id property with the BsonId attribute and currently my Guid is being stored as a string, which I've learnt isn't efficient nor great for aggregation. I've searched around a bit and have found bits and pieces of information, but still I'm not quite clear on how to do this correctly - just wondering if there is a Git example project out there or if someone is able to reply to this question showing how to do this properly. Greatly appreciated.

CraigM
  • 561
  • 8
  • 20
  • 1
    possible duplicate of http://stackoverflow.com/questions/11355792/with-mongodb-and-guids-for-the-id-of-documents-what-is-efficient-way-to-store-th?rq=1 – cpr43 Apr 12 '17 at 06:18

1 Answers1

0

It sounds like this is more a code design question.

The most common problem I've come across (that usually result in question like this), are something along the line of

"how to work with a model, without requiring native MongoDB dependencies in other projects."

Its not uncommon that data models will be used in cross projects, so having native Bson dependencies makes no sense. Hence, the solution that comes to mind is to change this ID to something like a Guid. (sensible).

I like to solve this problem with a base storage class, that use two attributes, whom are used if the project indeed knows the MongoDriver. (Otherwise it still works in other projects).

public class MongoObject
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }


    //Ohh yes, we extract the Timestamp directly from the ID, keeping this field index and ensured, time is common ground
    [BsonIgnore]
    public DateTime Timestamp
    {
        get 
        {
            if(Id != null)
            {
                return DateTimeOffset.FromUnixTimeSeconds(int.Parse(Id.Substring(0, 8), NumberStyles.HexNumber)).DateTime;
            }
            return DateTime.MinValue;
        }
    }
}

Now this base class comes along with a "Storage" class whom does ID conversion itself, because its mongo-aware.

Provided GET example for inspiration

    public async Task<T> Get<T>(string id) where T : class
    {
        IMongoCollection<T> collection = Collection<T>();
        var filter = Builders<T>.Filter.Eq("_id", ObjectId.Parse(id));
        return await collection.Find<T>(filter).FirstOrDefaultAsync();
    }

Now Guid also comes with the advantage that you can generate ID's on the fly, without having to involve a DB at all. (this is a second but equally powerful argument). I am not solving that here, but at least the solution offers good performance, due to using native ObjectId

Christopher Bonitz
  • 828
  • 1
  • 10
  • 22