无法筛选通过日期列存储在Mongo DB中的字符串

时间:2019-04-04 05:54:02

标签: c# mongodb .net-core

我有一个将数据写入MONGODB的应用程序。
在文档中,我有一个名为UpdatedOn的字段。在这种情况下,我以字符串格式编写日期时间,如下所示:

DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")

我知道我应该只使用日期类型,现在它已作为字符串存储在数据库中。
现在我有一个要求,要在2个日期之间根据此字段过滤数据。
像这样说:
开始日期:“ 01/01/2019”
结束日期:“ 31/01/2019”

这是我在下面使用的代码(不起作用)

IMongoCollection<Order> OrderCollection = GetOrderCollection();
List<OrderFilter> lstJobs;

FilterDefinitionBuilder<Order> OrderFilter = Builders<Order>.Filter;

DateTime start = Convert.ToDateTime("01/01/2019");   
DateTime end = Convert.ToDateTime("31/01/2019");

var filter = OrderFilter.Gte("UpdatedOn", start) &
OrderFilter.Lt("UpdatedOn", end);

var fields = Builders<Order>.Projection.Include(p => p.Id);
lstOrders = await OrderCollection.Find(filter).Project<OrderFilter>(fields).ToListAsync<OrderFilter>().ConfigureAwait(false);

OrderFilter类:

public class OrderFilter
{    
   [DataMember(Name = "id")]
   public string Id { get; set; }
}

订单类:

public class Order
{
   [DataMember(Name = "id")]
   public string Id { get; set; }

   [DataMember(Name = "UpdatedOn")]
   public string UpdatedOn { get; set; }
}

由于UpdatedOn是字符串,因此已经插入了一些数据。更改它不是实践。
在这种情况下,谁能帮我过滤。我可以在代码本身中进行任何类型转换或转换并进行过滤。
非常感谢!

1 个答案:

答案 0 :(得分:1)

您必须将字符串解析为Date才能将其他Date与之比较。 参见the docs here

要在C#中执行此操作,必须使用如下的Aggregate方法:

DateTime start = Convert.ToDateTime("01/01/2019");   
DateTime end = Convert.ToDateTime("31/01/2019");

var projectionDefinition = 
Builders<BsonDocument>.Projection.Exclude("convertedDate");

OrderCollection.Aggregate().AppendStage<BsonDocument>("{ $addFields: {convertedDate: { $toDate: '$UpdatedOn' }}}").Match(
    Builders<BsonDocument>.Filter.Gte(x => x["convertedDate"], new BsonDateTime(start))
    & Builders<BsonDocument>.Filter.Lte(x => x["convertedDate"], new BsonDateTime(end)))
    .Project(projectionDefinition).As<Order>();

通过使用舞台,您可能可以使它更漂亮。

例如,

var projectionDefinition = Builders<BsonDocument>.Projection.Exclude("convertedDate");
var expression = new BsonDocument(new List<BsonElement>
{
    new BsonElement("convertedDate", new BsonDocument(new BsonElement("$toDate", "$UpdatedOn")))
});

var addFieldsStage = new BsonDocument(new BsonElement("$addFields", expression));

var gteFilter = Builders<BsonDocument>.Filter.Gte(x => x["convertedDate"], new BsonDateTime(startDate));
var lteFilter = Builders<BsonDocument>.Filter.Lte(x => x["convertedDate"], new BsonDateTime(endDate));

var combinedFilter= Builders<BsonDocument>.Filter.And(gteFilter, lteFilter);

var result = coll.Aggregate().AppendStage<BsonDocument>(addFieldsStage).Match(combinedFilter).Project(projectionDefinition).As<Order>();

如果您在班级上方添加[BsonIgnoreExtraElements],则可以取消投影阶段。

或者在您的情况下,可以将其替换为当前使用的投影,并相应地设置.As<Type>