Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With mongodb and guids for the Id of documents what is efficient way to store the Guids to easily retrieve the actual Guid?

Tags:

I'm running version 2.06 of Mongodb and version (1.5) of the C# driver supplied by 10Gen.

Each of my entities has an Id property setup as such...

 [BsonId(IdGenerator = typeof(GuidGenerator))]  public Guid Id { get; set; } 

The Id field is stored as Binary - 3:UuidLegacy. Because of how it is stored when I call ToJson() on an entity it returns the following javascript object for the Id.

_id : Object  $binary: "some values here"  $type: "03" 

This is obviously because the data is being stored as Binary = 3:UuidLegacy. This make sense.

I want to use the actual Guid in my Javascript code. How efficient would it be for MongoDB if I made my Id properties look like the following?

 [BsonId(IdGenerator = typeof(GuidGenerator)),MongoDB.Bson.Serialization.Attributes.BsonRepresentation(BsonType.String)] public Guid Id { get; set; } 

This makes mongodb store my Id as a string. But how efficient is this really? I'm guessing the Binary format for my Id is better, but I really need the Guid.

How can I go from Binary - 3:uuidLegacy to the Guid I need in my json?

I guess another thought would be could I just use the $binary value that is sent to me? I use the Id to perform lookups and such as part of my query strings.

Thanks,

like image 471
RDotLee Avatar asked Jul 06 '12 04:07

RDotLee


People also ask

How to store large files in MongoDB?

Instead, MongoDB has a functionality specifically for storing large files and it goes by the name GridFS. GridFS divides the file into chunks and then stores them in the database. GridFS stores files in buckets, which is a group of MongoDB collections consisting of file chunks and file information.

What is GUID MongoDB?

GUIDs are often being used to identify custom objects created in software. Software developers very often explicitly store those identifiers in the database and do not rely on identifiers generated by the database system. MongoDB and the MongoDB drivers come with built-in support for the GUID/UUID data type.

Can we store files in MongoDB?

Large objects, or "files", are easily stored in MongoDB. It is no problem to store 100MB videos in the database. This has a number of advantages over files stored in a file system. Unlike a file system, the database will have no problem dealing with millions of objects.


1 Answers

Working with GUIDs has a few pitfalls, mostly related to how to work with the binary representation in the mongo shell and also to historical accidents which resulted in different drivers storing GUIDs using different byte orders.

I used the following code to illustrate the issues:

var document = new BsonDocument { { "_id", Guid.NewGuid() }, { "x", 1 } }; collection.Drop(); collection.Insert(document); Console.WriteLine("Inserted GUID: {0}", document["_id"].AsGuid); 

which when I ran it output:

Inserted GUID: 2d25b9c6-6d30-4441-a360-47e7804c62be 

when I display this in the mongo shell I get:

> var doc = db.test.findOne() > doc { "_id" : BinData(3,"xrklLTBtQUSjYEfngExivg=="), "x" : 1 } > doc._id.hex() c6b9252d306d4144a36047e7804c62be > 

Notice that even when displayed as hex the byte order doesn't match the original GUID. That's the historical accident I was talking about. All the bytes are there, they're just in an unusual order thanks to Microsoft's implementation of Guid.ToByteArray().

To help you work with GUIDs in the mongo shell you could copy the following file of helper functions to the directory where mongo.exe is stored:

https://github.com/rstam/mongo-csharp-driver/blob/master/uuidhelpers.js

The file has some brief documentation comments at the top that you might find helpful. To make these functions available in the mongo shell you need to tell the mongo shell to read this file as it starts up. See the following sample session:

C:\mongodb\mongodb-win32-x86_64-2.0.6\bin>mongo --shell uuidhelpers.js MongoDB shell version: 2.0.6 connecting to: test type "help" for help > var doc = db.test.findOne() > doc { "_id" : BinData(3,"xrklLTBtQUSjYEfngExivg=="), "x" : 1 } > doc._id.hex() c6b9252d306d4144a36047e7804c62be > doc._id.toCSUUID() CSUUID("2d25b9c6-6d30-4441-a360-47e7804c62be") > 

You could also use another of the helper functions to query for the GUIDs:

> db.test.find({_id : CSUUID("2d25b9c6-6d30-4441-a360-47e7804c62be")}) { "_id" : BinData(3,"xrklLTBtQUSjYEfngExivg=="), "x" : 1 } > 

As far as storing your GUIDs as strings, that's not an unheard of thing to do and it definitely makes viewing and querying the data in the mongo shell easier and avoids all the issues with different byte orders. The only disadvantage is that it uses more space (roughly double).

like image 163
Robert Stam Avatar answered Sep 25 '22 15:09

Robert Stam