使用mongodb和文档Id的指南什么是存储指南以便轻松检索实际Guid的有效方法?

时间:2012-07-06 04:23:38

标签: c# mongodb

我正在运行Mongodb 2.06版本和10Gen提供的C#驱动程序版本(1.5)。

我的每个实体都有一个Id属性设置......

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

Id字段存储为Binary - 3:UuidLegacy。由于我在实体上调用ToJson()时它的存储方式,它会为Id返回以下javascript对象。

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

这显然是因为数据存储为Binary = 3:UuidLegacy。这很有意义。

我想在我的Javascript代码中使用实际的Guid。如果我将我的Id属性看起来如下所示,它对MongoDB的效率如何?

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

这使得mongodb将我的Id存储为字符串。但这真的有多高效?我猜我的Id的二进制格式更好,但我真的需要Guid。

我怎样才能从二进制 - 3:uuidLegacy转到我在json中需要的Guid?

我想另一个想法是我可以使用发送给我的$ binary值吗?我使用Id执行查找,例如我的查询字符串的一部分。

谢谢,

1 个答案:

答案 0 :(得分:28)

使用GUID有一些缺陷,主要涉及如何使用mongo shell中的二进制表示以及历史事故导致不同的驱动程序使用不同的字节顺序存储GUID。

我使用以下代码来说明问题:

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

当我运行它时输出:

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

当我在mongo shell中显示它时,我得到:

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

请注意,即使显示为十六进制,字节顺序也不会与原始GUID匹配。那是我正在谈论的历史事故。所有字节都在那里,由于Microsoft实现了Guid.ToByteArray(),它们只是处于不寻常的顺序。

为了帮助您使用mongo shell中的GUID,您可以将以下帮助程序函数文件复制到存储mongo.exe的目录中:

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

该文件顶部有一些简短的文档注释,您可能会发现它们很有帮助。要在mongo shell中使这些函数可用,您需要告诉mongo shell在启动时读取该文件。请参阅以下示例会话:

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")
>

您还可以使用其他辅助函数来查询GUID:

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

至于将GUID存储为字符串,这不是一件闻所未闻的事情,它肯定使查看和查询mongo shell中的数据更容易,并避免了不同字节顺序的所有问题。唯一的缺点是它占用了更多的空间(大约两倍)。