我使用以下代码检索一些文档:
var client = new MongoClient(connectionString);
var database = client.GetDatabase(databaseName);
var collection = database.GetCollection<BsonDocument>(collectionName);
var json = "{created: {$gte: ISODate(\"2018-12-20T00:00:00.000Z\"), $lt:
ISODate(\"2018-12-21T00:00:00.000Z\")}}";
BsonDocument query = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(json);
var documents = collection.Find(query).Limit(10);
结果如下:
{ "_id" : CSUUID("75c5634c-b64b-4484-81f5-5b213228e272"), ..., "created" : ISODate("2018-12-20T23:59:13.375Z") }
尝试过滤_id时,我在检索同一文档时遇到麻烦。 这是我尝试过的过滤器(使用与上述相同的代码),但无法检索该文档:
var json = "{ \"_id\" : \"75c5634c-b64b-4484-81f5-5b213228e272\" }";
var json = "{ \"_id\" : CSUUID(\"75c5634c-b64b-4484-81f5-5b213228e272\") }";
var json = "{ \"_id\" : new BinData(4, \"TGPFdUu2hESB9VshMijicg==\") }";
var json = "{ \"_id\" : BinData(4, \"TGPFdUu2hESB9VshMijicg==\") }";
var json = "{ \"_id\" : new BinData(3, \"TGPFdUu2hESB9VshMijicg==\") }";
var json = "{ \"_id\" : BinData(3, \"TGPFdUu2hESB9VshMijicg==\") }";
var json = "{ \"_id\" : { $eq: \"TGPFdUu2hESB9VshMijicg==\" } }";
var json = "{ \"_id\" : { $binary: \"TGPFdUu2hESB9VshMijicg==\", $type: 4 } }";
var json = "{ \"_id\" : { $binary: \"TGPFdUu2hESB9VshMijicg==\", $type: 3 } }";
注意,TGPFdUu2hESB9VshMijicg==
是通过从GUID获取以64为基数的字符串来检索的,如下所示:
Convert.ToBase64String((new Guid("75c5634c-b64b-4484-81f5-5b213228e272")).ToByteArray())
所有查询都不会引发任何异常,但是它们不返回任何文档。
答案 0 :(得分:4)
甚至在创建MongoClient()之前添加此命令即可为我解决问题:
BsonDefaults.GuidRepresentation = GuidRepresentation.Standard;
在C#端,MongoDB驱动程序似乎将其解释为二进制子类型为3的UUID。但是,保存在集合中的文档的二进制子类型为4。
此外,在此更改之后,检索到的文档将显示“ UUID()”而不是“ CSUUID()”:
{ "_id" : UUID("75c5634c-b64b-4484-81f5-5b213228e272"), ..., "created" : ISODate("2018-12-20T23:59:13.375Z") }
经过比我更愿意承认的时间搜索网络并测试了许多理论之后,突破来自于浏览本文:https://www.codeproject.com/Articles/987203/%2FArticles%2F987203%2FBest-Practices-for-GUID-data-in-MongoDB
该链接的摘录:
MongoDB驱动程序通常将UUID与旧版存储为Binary字段 默认分配的0x03子类型。可以更改此配置:
C#:
您可以覆盖驱动程序的默认设置并将其配置为使用 二进制0x04子类型,方法是修改 BsonDefaults.GuidRepresentation:
BsonDefaults.GuidRepresentation = GuidRepresentation.Standard;
您还可以在以下位置修改GuidRepresentation 服务器,数据库和收集级别。
编辑:
这是我最终用于json过滤器的内容:
var json = "{ \"_id\" : UUID(\"75c5634c-b64b-4484-81f5-5b213228e272\") }";
答案 1 :(得分:3)
MongoDb C#驱动程序做了很多工作,试图使您远离Json(Bson)表示形式。 为了简化起见,您有3种使用C#来使用MongoDb的方法。
BsonDocument
类。当然,这三个因素的结合会使情况变得更糟:-)
因此,在您的情况下,这是您将如何使用BsonDocument方式(不使用任何JSON):
var client = new MongoClient(myConnectionString);
var db = client.GetDatabase("myDb");
var guid = Guid.NewGuid();
// create an untyped document
var doc = new BsonDocument { { "_id", guid } };
var coll = db.GetCollection<BsonDocument>("myColl");
coll.InsertOne(doc);
// Builders<T> is central to help you build all sorts of mongodb JSON jargon (filters, sort, projections, etc.)
// instead of building it by yourself
var filter = Builders<BsonDocument>.Filter.Eq(new StringFieldDefinition<BsonDocument, Guid>("_id"), guid);
var foundDoc = coll.Find(filter).FirstOrDefault();
Console.WriteLine(foundDoc["_id"]);
这是您可以执行键入文档方式(不带任何JSON和不带任何BsonDocument)的方法:
var client = new MongoClient(myConnectionString);
var db = client.GetDatabase("myDb");
var guid = Guid.NewGuid();
// create a class
var doc = new MyDoc { Id = guid };
var coll = db.GetCollection<MyDoc>("myColl");
coll.InsertOne(doc);
// we use a type that correspond to our busines layer/logic
// that's the easier way because you can use Linq syntax so we're far from JSON and document issues
// plus it's super readable in C#
var foundDoc = coll.Find(d => d.Id == guid).FirstOrDefault();
Console.WriteLine(foundDoc.Id);
...
// the typed-document (class)
class MyDoc
{
[BsonId]
public Guid Id { get; set; }
... other properties...
}
如您所见,最后一种方法要简单得多,但是我们不能总是使用它。
顺便说一句,令人遗憾的是,驱动程序不允许从MyDoc
派生BsonDocument
,因为我们确实拥有两全其美的优势(编译但抛出……。如果MongoDb C#开发人员阅读了此内容。 ..)
现在,关于GUID,您会注意到Console.WriteLine(foundDoc["_id"])
显示UuidLegacy:0x87fa981983de774b998868046e257b19
,因为MongoDb具有GUID的历史记录。
您发现,可以更改BsonDefaults.GuidRepresentation
。默认情况下为CSharpLegacy
。
以下是在整个代码(客户端或服务器)中将guid显示为字符串时使用的前缀列表:
2和3方法也使您免受这些“内部” MongoDb问题的困扰。如果使用这些,则不必更改BsonDefaults.GuidRepresentation
。
因此,我的建议是在使用C#编程MongoDb时,尽量远离Json。