如何仅按年份过滤?

时间:2019-07-24 05:40:40

标签: c# mongodb

我想查找与给定年份匹配的文档。

我正在使用MongoDb.Driver,当前需要此库的解决方案。

int year = 2019;
var filter = Builders<CubesDataMdb>.Filter.Eq(x => x.DateOfCreation.Year, year);
var response = await Collection.Find(filter).FirstOrDefaultAsync();

异常说:“无法确定x => x.DateOfCreation.Year的序列化信息。” 我希望输出是一个文档,无论日期的另一部分是什么,该年份等于我的变量

2 个答案:

答案 0 :(得分:1)

您必须按范围进行搜索:

int year = 2019;
DateTime startDate = new DateTime(year, 1, 1);
DateTime endDate = new DateTime(year + 1, 1, 1);
var filter = Builders<CubesDataMdb>.Filter.Gte(x => x.DateOfCreation, startDate)
            & Builders<CubesDataMdb>.Filter.Lt(x => x.DateOfCreation, endDate);
var response = await Collection.Find(filter).FirstOrDefaultAsync();

因此,这里我们要确定两个日期:2019/01/012020/01/01。然后,我们可以搜索日期大于或等于2091/01/01但小于2020/01/01的所有记录。

答案 1 :(得分:0)

由于已经得到答复,我将提供一种替代方法以供将来参考(如果有人需要)。

  

首先,问题无法确定x => x.DateOfCreation.Year

的序列化信息。

出现此错误的原因是因为c#驱动程序正在翻译给定的linq语句:

int year = 2019;
var filter = Builders<CubesDataMdb>.Filter.Eq(x => x.DateOfCreation.Year, year);
var response = await Collection.Find(filter).FirstOrDefaultAsync();

对于mongo shell脚本,如:

db.Collection.find({"{document}{DateOfCreation}.Year":{$eq:2019}})

因此,Mongodb c#驱动程序无法将其映射到任何字段,因为类{document}{DateOfCreation}.Year或数据库中存储的任何文档中都不存在字段CubesDataMdb > ps一个简单的解释是MongoDB不支持field.Year 的linq转换语法。

因此,除了John提供的答案之外,还有另一种方法。

汇总:

使用ViewModel,其属性与模型CubesDataMdb相同,除了附加属性

public int Year { get; set; }

然后通过使用$addFields从对象DateOfCreation中提取年份部分来构造一个$year阶段,以在聚合管道中使用(通过假设DateOfCreation具有mongo日期而不是字符串日期)为:

BsonDocument expressionString = new BsonDocument(new List<BsonElement>() {
    new BsonElement("Year", new BsonDocument(new BsonElement("$year", "$DateOfCreation"))),
});
BsonDocument addFieldsStageMongo = new BsonDocument(new BsonElement("$addFields", expressionMongo));
//adding the stage to the aggrigation pipeline
var response = await Collection
              .Aggregate()
              .AppendStage<BsonDocument>(addFieldsStageMongo)
              .Match(m=>m.Year == year)//using the filter on the newly added field of pipeline
              .FirstOrDefaultAsync();

mongo shell等效查询为:

db.Collection.aggregate([
{$addFields:{
    Year:{$year:"$DateOfCreation"}
}},
{
    $match:{
        "Year":2019
    }
}
])