Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
385 views
in Technique[技术] by (71.8m points)

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

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,

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:mongodbmongodb-win32-x86_64-2.0.6in>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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...