【发布时间】:2014-05-24 00:50:18
【问题描述】:
我是 Mongo DB 的新手,我正在尝试弄清楚如何进行一些更复杂的查询。我有一个包含DateTime 嵌套数组的文档。
这是我的数据:
{ "_id" : ObjectId("537d0b8c2c6b912520798b76"), "FirstName" : "Mary", "LastName" : "Johnson", "Age" : 27, "Phone" : "555 555-1212", "Dates" : [ISODate("2014-05-21T21:34:16.378Z"), ISODate("1987-01-05T08:00:00Z")] }
{ "_id" : ObjectId("537e4a7e2c6b91371c684a34"), "FirstName" : "Walter", "LastName" : "White", "Age" : 52, "Phone" : "800 123-4567", "Dates" : [ISODate("1967-12-25T08:00:00Z"), ISODate("2014-12-25T08:00:00Z")] }
我想要做的是返回 Dates 数组包含一个范围之间的值的文档。在我的测试用例中,范围是 1/1/1987 和 1/10/1987,所以我希望取回上面列出的第一个文档(Mary Johnson),因为 1/5/1987 在该 Dates 数组中并且介于 1/1 之间/1987 年和 1987 年 1 月 10 日。
我希望能够同时使用 MongoDB 命令行实用程序和 C# 驱动程序来执行此操作。
使用 C# 驱动程序,我尝试了以下 LINQ 查询(基于 MongoDB 文档中的示例):
DateTime beginRange = new DateTime(1987, 1, 1);
DateTime endRange = new DateTime(1987, 1, 10);
var result = from p in people.AsQueryable<Person>()
where p.Dates.Any(date => date > beginRange && date < endRange)
select p;
以上代码从 C# 驱动程序代码中引发异常:
Any 仅支持序列化为文档的项目。当前的序列化程序是DateTimeSerializer,必须实现IBsonDocumentSerializer 才能参与Any 查询。
当我尝试直接查询 MongoDB 数据库时,我尝试了以下操作:
db.People.find( {Dates: { $gt: ISODate("1987-01-01"), $lt: ISODate("1987-01-10") } } )
此查询会返回两个文档,而不仅仅是在其Dates 数组中包含1/5/1987 的文档。
编辑:
我从 C# 驱动程序中找到了一种方法。它不像我想要的那样干净,但它是可行的。
我认为,既然有一种方法可以直接从命令实用程序中获取我想要的东西,那么如果从 C# 驱动程序中也必须有一种方法,只需从 C# 驱动程序执行相同的查询即可。
string command = "{Dates : { $elemMatch : { $gt: ISODate(\"" + beginRange.ToString("yyyy-MM-dd") + "\"), $lt: ISODate(\"" + endRange.ToString("yyyy-MM-dd") + "\") } } } ";
var bsonDoc = BsonSerializer.Deserialize<BsonDocument>(command);
var queryDoc = new QueryDocument(bsonDoc);
MongoCursor<Person> p = people.Find(queryDoc);
【问题讨论】:
标签: c# .net linq mongodb mongodb-.net-driver