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

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

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

Id字段存储为二进制-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?

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

谢谢

推荐答案

使用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中使用GUI,您可以将以下助手函数文件复制到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")
>

您还可以使用另一个助手函数来查询GUI:

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

至于将您的guid存储为字符串,这并不是前所未闻的事情,而且它确实可以让查看和查询mongo shell中的数据变得更容易,并避免了不同字节顺序的所有问题.唯一的缺点是它占用了更多的空间(大约是原来的两倍).

Mongodb相关问答推荐

Mongo如何找到字段排除特殊字符

无法从我的NextJS 14应用程序中的Redux工具包2.0中提取数据

如何在 kubernetes 中获取分片 mongodb 的备份

使用Go的Mongo驱动程序,从MongoDB文档中获取元素并更新其值需要帮助

将子文档中的所有字段设置为 false,然后在单个查询中将第二个字段设置为 true

使用 homebrew 和 Xcode 8.1.1 安装 Mongodb 失败

使用模拟 MongoDB 服务器进行单元测试

MongoDB 文档操作是原子的和隔离的,但它们是否一致?

Meteor 如何接收对 MongoDB 查询结果的更新?

mongodb - 查找具有最接近整数值的文档

使用 mgo 存储嵌套 struct

在 Nodejs 中配置最大旧空间大小

Mongoose.js 通过一个 connect() 调用创建到 MongoDB 的多个连接

如何使用 mgo 和 Go 查询 MongoDB 的日期范围?

mongo - Ruby连接问题

为什么我新创建的 mongodb 本地数据库增长到 24GB?

MongoDB 用 $type 匹配一个数组?

何时使用Singleton单例、Transient和使用 Ninject 和 MongoDB 的请求

Mongodb Compass 无法在 Ubuntu 18.10 中打开

即使重新安装后,Mongo 仍在等待 27017