【问题标题】:MongoDB Find | Exception - is not supportedMongoDB 查找 |例外 - 不支持
【发布时间】:2019-02-03 14:26:05
【问题描述】:

我有一个 MongoDB 数据库,其中我以 Unix 格式存储日期。

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

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();

【问题讨论】:

  • WHERE 可以工作吗?
  • 我有点没看懂问题

标签: c# mongodb find


【解决方案1】:

我认为Find 有一个“支持的表达式”列表,可以(通过 lambda)用作参数 - 具有过滤器的含义。 .Net 驱动的官方文档中列出了支持的表达式(例如)here

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

恕我直言,您可以重写您的查询,将 DateTime.UtcNow 转换为 unix 时间戳,并将转换后的值用作 eq 过滤器(long 类型)用于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 时间戳应用 only date 过滤器。 由于 .Net MongoDb 驱动程序无法将日期转换为应用提供的格式的字符串,我们可以尝试将我在上一个示例中使用的相反方法应用于当天的开始第二天开始,将== 条件转换为基于&lt;&gt;= 的新条件:

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();

【讨论】:

  • 这是问题,我需要比较日期,而在Unix中也有时间,它是不同的/为此,我将其转换为字符串MM/dd/yyyy
  • 好的,我知道了。 .Net MongoDb 驱动程序无法将日期转换为应用您提供的格式的字符串,因此...解决方案可以从系统获取当前日期时间,获取与一天的开始和开始对应的 long 值第二天并使用&lt;&lt;= 重写查询...我尝试编辑我的答案以使用这种方法。
猜你喜欢
  • 2012-09-15
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多