MongoDriver c# 从日期字段按月份名称过滤

MongoDriver c# Filter by month Name from a Date Field

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

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

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

选择一个月的所有文档时,条件需要检索所有具有Greather的文件,该文件比或等于本月的开始日期,少于下一个月的开始日期,例如所以:

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 代表应该检索数据的月份。

默认 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 函数一样