【问题标题】:Unable to filter through date column which is stored as string in Mongo DB无法过滤在 Mongodb 中存储为字符串的日期列
【发布时间】:2019-04-04 05:54:02
【问题描述】:

我有一个将数据写入 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 是字符串并且已经插入了一些数据。改变它是不切实际的。
在这种情况下,谁能帮我过滤一下。我可以在代码本身中进行任何类型转换或转换并进行过滤。
非常感谢!

【问题讨论】:

  • 开始,将 DateTime start = Convert.ToDateTime("01/01/2019"); 更改为 DateTime start = Convert.ToDateTime("2019/01/01") 以避免日月歧义
  • @JohnB 我做到了。虽然没有帮助

标签: c# mongodb .net-core


【解决方案1】:

您必须将字符串解析为 Date 才能与其他 Dates 进行比较。 见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&lt;Type&gt;

【讨论】:

    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 2019-08-17
    • 2020-11-29
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    相关资源
    最近更新 更多