23

我正在运行 2.06 版的 Mongodb 和 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。

如何从 Binary - 3:uuidLegacy 转到我在 json 中需要的 Guid?

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

谢谢,

4

1 回答 1

36

使用 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 不匹配。这就是我所说的历史事故。所有字节都在那里,由于微软实施了 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 中的数据更加容易,并避免了不同字节顺序的所有问题。唯一的缺点是它使用了更多的空间(大约是两倍)。

于 2012-07-06T14:34:55.113 回答