【问题标题】:MongoDriver c# Filter by month Name from a Date FieldMongoDriver c# 按日期字段中的月份名称过滤
【发布时间】:2021-11-25 13:24:23
【问题描述】:

要求:需要按月份过滤mongo文档(数据以日期时间存储在mongo中)

使用代码: var expenseMonthFilter = Builders<MyDocument>.Filter.Eq(i => i.ExpenseDate.Month, 12);

异常获取:Unable to determine the serialization information for i => i.ExpenseDate.Month.

【问题讨论】:

  • 您是要检索某个月份(例如2021年1月)的所有文档还是要检索各个年份1月的所有文档?
  • 嗨@Markus 所选月份(当年)的所有记录
  • mongo 中基本查询之外的任何内容通常都需要聚合

标签: c# mongodb mongodb-.net-driver


【解决方案1】:

在选择一个月的所有文档时,条件需要检索具有GRATERED的所有文档,该文档比或等于月的开始日期,而不是下个月的开始日期,如下所示:

var startOfMonth = new DateTime(selectedYear, selectedMonth, 1, 0, 0, 0, DateTimeKind.Utc);
var startOfNextMonth = startOfMonth.AddMonths(1);
var bldr = Builders<MyDocument>.Filter;
var expenseMonthFilter = bldr.And(
    bldr.Gte(x => x.ExpenseDate, startOfMonth), 
    bldr.Lt(x => x.ExpenseDate, startOfNextMonth));

请注意,在上面的示例中,selectedYear 代表年份,selectedMonth 代表应检索数据的月份。

【讨论】:

    【解决方案2】:

    默认的 mongo 日期只是一个数字而不是日期,您必须应用外部转换将其转换为日期,为此您需要在查询之前使用聚合来转换数据

    一个选项是使用分组来预选数据,即

    PipelineDefinition<BsonDocument, BsonDocument> pipeline = new BsonDocument[]
    {
        new BsonDocument("$group", new BsonDocument()
                .Add("_id", new BsonDocument()
                        .Add("month", new BsonDocument()
                                .Add("$month", "$yourDateField")
                        )
                )
                .Add("data", new BsonDocument()
                        .Add("$addToSet", "$$ROOT")
                )), 
        new BsonDocument("$match", new BsonDocument()
                .Add("_id.month", 6.0))
    };
    

    如果您只想按月对数据进行分组,那么您不需要匹配阶段,每个组的形式为

    _id.nonth:int,
    data:<collection of base docs that are in that month>
    

    另一种选择是在匹配之前重新投影每个文档

    PipelineDefinition<BsonDocument, BsonDocument> pipeline = new BsonDocument[]
    {
        new BsonDocument("$project", new BsonDocument()
                .Add("month", new BsonDocument()
                        .Add("$month", "$yourDateField")
                )
                .Add("root", "$$ROOT")), 
        new BsonDocument("$match", new BsonDocument()
                .Add("month", 6.0))
    };
            
    

    其中任何一个都会被调用

    var cursor = await collection.AggregateAsync(pipeline, options)
    

    如果您想包含对 $year 函数的简单调用的年份,例如我有 $month 函数

    【讨论】:

      猜你喜欢
      • 2015-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多