2014-02-05 3 views
0

У меня есть база данных MongoDB, в которой хранятся записи, имеющие временную метку, когда они были созданы, и значение. Я подключаюсь к этой базе данных и запрашиваю ее с помощью официального драйвера C#.Получить ближайшие значения за пределами диапазона запросов

Обычный случай использования включает в себя получение всех записей> = startDateTime и < = endDateTime, что довольно прямолинейно.

Однако есть моменты, когда точки данных достаточно далеки от начала и конца периода, который мне понадобится для интерполяции значения в startDateTime и endDateTime. Для этого мне, очевидно, нужна последняя запись перед startDateTime и первая запись после endDateTime. Это легко сделать с тремя запросами, но я бы хотел избежать этого, чтобы сократить количество обращений в базу данных.

Можно ли достичь этого одним запросом?

Edit: так как меня попросили уточнить случай использования:

у меня есть датчик, который регистрирует температуру каждый час. Температура и временная метка сохраняются в коллекции MongoDB. Теперь я хочу составить график температур за вчерашний день, поэтому я прошу записать все записи, имеющие временную метку> = 2014.02.04 00:00:00 и временную отметку < 2014.02.05 00:00:00

Это оказывается, что этот датчик регистрируется через 55 минут в каждый час, поэтому моя первая точка данных составляет 55 минут, а мой последний пункт данных находится в 5 минутах от конца вчера.

В дополнение к 24 значениям, которые относятся к моему временному диапазону, я хотел бы получить значения в 2014.02.03 23:55:00 и в 2014.02.05 00:55:00, чтобы я мог интерполировать. Это необходимо обобщить на получение последней записи до начала моего периода и первой записи после окончания моего периода, так как я не знаю, как часто регистрируется журнал регистрации, когда он регистрируется, или если он находится в автономном режиме в любой момент.

Edit2: сокращенный вариант моего кода, как сегодня:

 //Get last record before the period 
     var cursor = collection.Find(
      Query.LT("DateTime", startDateTime) 
     ); 
     cursor.Limit = 1; 
     cursor.SetSortOrder(SortBy.Descending("DateTime")); 
     //Not shown: getting the record from the cursor and adding it to the collection 

     //Getting all records that fall within the specified period 
     cursor = collection.Find(
      Query.And(
       Query.GTE("DateTime", startDateTime), 
       Query.LTE("DateTime", endDateTime)) 
     ); 
     //Not shown: getting the records from the cursor and adding them to the collection 

     //Get first record after the period 
     cursor = collection.Find(
      Query.GT("DateTime", endDateTime) 
     ); 
     cursor.Limit = 1; 
     cursor.SetSortOrder(SortBy.Ascending("DateTime")); 
     //Not shown: getting the record from the cursor and adding it to the collection 
+0

Я никогда не использовал MongoDB. В SQL Server вы можете объединить эти три запроса в один с несколькими UNION. Поддерживает ли MongoDB UNION или эквивалент? – jmcilhinney

+0

Да, я в основном семейный с SQL. Похоже, есть оператор OR, который можно использовать: http://stackoverflow.com/questions/14924129/union-on-same-collection-in-mongodb –

+0

Не уверен, что я понимаю ваш прецедент. Вы говорите, что пытаетесь найти, какие даты начала и окончания использовать для использования в другом запросе? Это может помочь, если вы публикуете информацию о том, что вы на самом деле делаете в своем вопросе, для уточнения. –

ответ

0

Если вы не знаете, как часто датчик (ы) журнал И если есть на самом деле чтение записано своевременно «за пределами» желаемых 24 часов, тогда лучший подход - сделать 3 заявления.

Удаление одного из двух ограничений может привести к получению результатов в меньших операциях.

Если вы обеспокоены тем, что 3 запроса являются «медленными», вы должны работать над тем, чтобы запросы выполнялись быстрее, например, с помощью индекса.

0

Кажется, что ваш подход ищет аналог SQL UNION, как это подразумевается в трех операциях запроса. И операции очевидны в этом подходе:

  1. Найти все записи в течение начала дня и в конце диапазона дня
  2. Найти первую запись, которая происходит до начала диапазона дня
  3. Найти последний запись, которая происходит после окончания дневного диапазона

Хотя это ясно, это может быть только я, но я не вижу полезности этого подхода. Из того, что вы пишете, кажется, вы пытаетесь собрать 24 балла за график, и этот график будет следовать за 24-часовым периодом.Таким образом, он увидит, что объединенные результаты трех выпущенных запросов вернут между лучшими 26 записями и в худшем случае 2 записями. Или, возможно, один, если запись не будет заранее и в зависимости от того, когда запрос был запущен.

Учитывая, что есть две записи, которые может хорошо упасть из вашего дневного диапазона и не быть полезной, кроме как сказать, что не было активности в часы или дни до или после.

Я знаю, что это не ответ кода, но аналог UNION не выполняет то, что вы делаете, но я могу предположить, что, возможно, вам не нужно делать то, что вы делаете.

Выполняя то, что я вижу и что, как представляется, является функцией, я не вижу, что не так, просто выбирая записи меньше, чем в конце дня + 1 час и ограничивая последние 26, в порядке убывания сортировки , Оттуда вы можете принимать любые решения, которые вы хотите, для представления данных, и мы говорим о очень небольшом числе результатов.

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

+0

«Это необходимо обобщить на получение последней записи до начала моего периода и первой записи после окончания моего периода, так как я не знаю, как часто журналы датчиков, когда он регистрируется, или если он в автономном режиме в любой момент ». - Возможно, я был неясно, но приведенный выше вариант использования - один из многих возможных. Так же легко может быть случай, когда датчик регистрируется каждую секунду, мне нужно смотреть на все записи в течение полугода, и, случается, происходит дневной перерыв, охватывающий начало периода. Вот почему мне нужно общее решение. –

Смежные вопросы