MongoDB查找|例外-不支持 [英] MongoDB Find | Exception - is not supported

查看:90
本文介绍了MongoDB查找|例外-不支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MongoDB数据库,并且在其中以Unix格式存储日期.

I have a MongoDB database, and in it I store dates in Unix format.

但是当我尝试进行查找并在其中实现过滤器时,它给了我一个错误.

But when I try to make a Find and implement a filter in it, it gives me an error.

FromUnixTimeSeconds({ViewsToday.Date}).ToString("MM/dd/yyyy") is not supported.
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.GetFieldExpression(Expression expression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(Expression variableExpression, ExpressionType operatorType, ConstantExpression constantExpression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateAndAlso(BinaryExpression node)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
   at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)

我的代码是:

    var results = await Settings.DataBase.GetCollection<Video>("Videos")
        .Find(x => x.ViewsToday != null && DateTimeOffset.FromUnixTimeSeconds(x.ViewsToday.Date).ToString("MM/dd/yyyy") == DateTime.UtcNow.ToString("MM/dd/yyyy"))
            .ToListAsync();

推荐答案

我认为 Find 列出了可以使用的受支持的表达式"列表(通过 lambda )作为参数-具有过滤器的含义.在(此处中列出支持的表达式.Net驱动程序的官方文档.

I think Find has a list of "supported expressions" which can be used (through a lambda) as parameter - with the meaning of a filter. Suported expression are listed (e.g.) here in the official documentation of .Net driver.

在C#代码中,您可以使用任何C#有效表达式,但是当您使用驱动程序不支持的表达式时,会显示错误.

In C# code you can use any C# valid expression, but when you use an expression not supported by the driver you obtain the error you're showed.

恕我直言,您可以将将 DateTime.UtcNow 转换为unix时间戳的查询重写,并将转换后的值用作 eq 过滤器(类型为 long )表示 x.ViewsToday.Date .

IMHO you can rewrite your query converting DateTime.UtcNow into unix timestamp and usig the converted value as eq filter (of type long) for x.ViewsToday.Date.

您可以尝试以下操作:

var now = DateTime.UtcNow.ToUnixTimeSeconds();
var results = await Settings.DataBase.GetCollection<Video>("Videos")
        .Find(x => x.ViewsToday != null && x.ViewsToday.Date == now)
            .ToListAsync();

已编辑

如评论中所述,问题是在包含时间信息的Unix时间戳上也应用了仅日期过滤器.由于.Net MongoDb驱动程序无法使用提供的格式将日期转换为字符串,因此我们可以尝试将我在上一个示例中使用的相反方法应用于当天的开始第二天开始,根据< > = == 条件转换为新条件:

As reported in the comment, the problem is to apply an only date filter on an Unix timestamp containg time information, too. Since .Net MongoDb driver is unable to convert dates to string applying provided format, we can try to apply the opposite approach I used in the previous example to both the start of the current day and the start of next day, converting the == condition to a new condition based on < and >=:

var now = DateTime.UtcNow;
var currentDate = now.Date;
var tomorrow = currentDate.AddDays(1);
var left = currentDate.ToUnixTimeSeconds();
var right = tomorrow.ToUnixTimeSeconds();

var results = await Settings.DataBase.GetCollection<Video>("Videos")
        .Find(x => x.ViewsToday != null && 
              x.ViewsToday.Date >= left && 
              x.ViewsToday.Date < right)
            .ToListAsync();

这篇关于MongoDB查找|例外-不支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆