您好我想在MongoDB中使用C#驱动程序查找两个日期(时间)之间的条目,但我使用的Find + Filter方法忽略时间并仅按日期搜索(我认为)。我做错了什么?
我的POCO:
public class TestClassForMongo
{
public ObjectId Id { get; set; }
public DateTime CreatedDateUtc { get; set; }
public string Message { get; set; }
}
我的搜索代码:
IMongoCollection<TestClassForMongo> collection = db.GetCollection<TestClassForMongo>("mongoTest");
var filterBuilder = Builders<TestClassForMongo>.Filter;
var filter = filterBuilder.Gt("CreatedDateUtc", new DateTime(2016, 03, 04, 21, 0, 0)) &
filterBuilder.Lt("CreatedDateUtc", new DateTime(2016, 03, 04, 22, 0, 0));
List<TestClassForMongo> searchResult = collection.Find(filter).ToList();
上面的代码返回空数组,尽管如此:
collection.Find(filterBuilder.Empty).First().CreatedDateUtc
返回日期:“2016-03-04 21:21:54”
MongoDB 3.2.3,C#MongoDB驱动程序2.2.3
驱动程序文档:https://docs.mongodb.org/getting-started/csharp/query/
回答:
我没有提供足够的信息让任何人回答这个问题,问题是时区和UTC相关问题,也是非常基本的问题。我使用DateTime.UtcNow
将日期存储在数据库中。它存储为"CreatedDateUtc" : ISODate("2016-03-04T21:21:54.836Z")
。在C#中获取此值将返回一个实际上是UTC日期的日期(Kind
属性为UTC
),其中btw由db中值的“Z”后缀表示。将此UTC日期与新的DateTime()进行比较没有太大意义,因为后者在您的时区中创建了一个日期,该日期可能与+0(UTC)不同。
因此,一个选项是为此过滤器创建日期:
new DateTime(2016, 03, 04, 21, 0, 0).ToUniversalTime()
或修改小时部分以适应时区差异,在我的示例中,它将增加1小时(因为我在+1时区)。
实际上,我所在的时区存储的时间是22:21:54
。如果我使用在我的时区创建的日期在22:00:00和23:00之间进行搜索,我会得到正确的结果。
答案 0 :(得分:3)
在dateTime字段上添加BSON属性(见下文),
您可以使用linqu语法来构建此类查询
var min = new DateTime(2016, 03, 03, 22, 0, 0);
var max = (new DateTime(2016, 03, 03, 23, 0, 0));
List<TestClassForMongo> searchResult = collection.Find(
x => x.CreatedDateUtc > min &
x.CreatedDateUtc < max
).ToList();
BSON ATTRIBUTE
public class TestClassForMongo
{
public ObjectId Id { get; set; }
[BsonDateTimeOptions]
public DateTime CreatedDateUtc { get; set; }
public string Message { get; set; }
}
下面的linqPad转储: