MongoDB Найти |Исключение - не поддерживается - PullRequest
0 голосов
/ 03 февраля 2019

У меня есть база данных 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();

1 Ответ

0 голосов
/ 03 февраля 2019

Я думаю, Find имеет список «поддерживаемых выражений», которые можно использовать (через лямбда ) в качестве параметра - со значением фильтра.Поддерживаемые выражения перечислены (например) здесь в официальной документации драйвера .Net.

В коде 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();

EDITED

Как отмечается в комментарии, проблема заключается в применении только дата фильтр по метке времени Unix, также содержащий информацию о времени.Поскольку драйвер .Net MongoDb не может преобразовать даты в строку, используя предоставленный формат, мы можем попытаться применить противоположный подход, который я использовал в предыдущем примере, к началу текущего дня и началуследующего дня , преобразование условия == в новое условие на основе < и >=:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...