Почему запрос MongoDB не возвращает никаких результатов?(Фильтрация по дате отсечения) - PullRequest
1 голос
/ 01 апреля 2019

Вот запрос C #, который у меня есть:

public Task<UserStats> GetStatsForUserWithId(string userId, DateTime? cutoffDate = null)
{
    var idFilter = Builders<UserStats>.Filter.Eq(s => s.UserId, userId);
    var cutoffDateFilter = Builders<UserStats>.Filter.Lt(s => s.Timestamp, cutoffDate ?? DateTime.MaxValue);

    return _stats
        .Find(idFilter & cutoffDateFilter)
        .SortByDescending(stats => stats.Timestamp)
        .FirstOrDefaultAsync();
}

Вот эквивалентный запрос MongoDB, который я пытаюсь повторить - это работает:

db.getCollection('stats').find({
    "UserId": "5ca13b15d74d5633c45a3304",
    "Timestamp": { $lt: ISODate("2022-04-01T02:17:04+0000") }
}).sort({ 
    "Timestamp": -1 
}).limit(1)

Вот сущность, являющаясясохраняется, если это имеет значение:

public class UserStats
{ 
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
    public string UserId { get; set; }
    public Stats1V1 Stats1V1 { get; set; }
    public Stats2V2 Stats2V2 { get; set; }
    public StatsOverall StatsOverall { get; set; }
    public DateTime Timestamp { get; set; }
}

Проблема: Когда я запускаю запрос C #, я не получаю никаких результатов.Запрос MongoDB работает нормально, предполагая, что есть некоторая разница между этими двумя, которых я не вижу.Что это?

Вот пример объекта того, что хранится в БД, с нерелевантными полями, опущенными для краткости:

{
    "_id" : ObjectId("5ca167ac8c7e7250843553a4"),
    "UserId" : "5ca13b15d74d5633c45a3304",
    "Stats1V1" : {
        // omitted a bunch of fields
    },
    "Stats2V2" : {
        // omitted a bunch of fields
    },
    "StatsOverall" : {
        // omitted a bunch of fields
    },
    "Timestamp" : ISODate("2019-04-01T01:21:48.861Z")
}

РЕДАКТИРОВАТЬ: я должен отметить, чтозапрос работал отлично до добавления фильтра даты отсечения.Сортировка, Id-фильтр и т. Д. Работали раньше, все перестало работать, когда я добавил новый фильтр даты отсечения.

1 Ответ

1 голос
/ 02 апреля 2019

Итак, я решил проблему с помощью коллеги.

Оказалось, что это на самом деле вызвано тем, что методы контроллера C # Web API обрабатывают параметры запроса, которые не указаны.Я предположил (будучи новичком в .NET), что, как и любой параметр функции в C #, который не предоставляется, по умолчанию он равен нулю.Однако для параметров запроса это, очевидно, не тот случай - он предполагает значение по умолчанию начала нашего календаря.

Я объединял нулевые значения в какую-то разумную дату в будущем, но эта операция никогда не будет выполненапотому что переменная на самом деле никогда не была нулевой.

Я должен был обнаружить это, когда прошел через нее в отладчике, но я, очевидно, как-то пропустил ее, не зная как.

Однако я хотелподелиться информацией, которая помогла мне найти причину проблемы - я использовал инструменты профилирования, встроенные в MongoDB, чтобы отследить причину.

Запустив следующие строки в оболочке MongoDB:

db.setProfilingLevel(0)
db.system.profile.drop()
db.createCollection( "system.profile", { capped: true, size:4000000 } )
db.setProfilingLevel(2)

чтобы включить профилирование, выполнить мой вызов API, а затем запустить следующую строку в оболочке Mongo:

db.system.profile.find().pretty() 

Мне удалось получить этот вывод (сокращенный до важной части):

    "command" : {
        "find" : "stats",
        "filter" : {
            "Timestamp" : {
                "$lt" : ISODate("0001-01-01T00:00:00Z")
            }

// omitted

Обратите внимание, что отметка времени здесь находится в 0001 году. Это привело меня к исследованию, как она получила это значение, wкоторый был в конечном итоге обнаружен отладчиком.

Надеюсь, этот подход может помочь кому-то еще в будущем.

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