Лучший NoSql для запросов диапазонов дат? - PullRequest
4 голосов
/ 18 апреля 2011

Учитывая магазин, который представляет собой набор документов JSON в (приблизительной) форме:

{
PeriodStart: 18/04/2011 17:10:49 
PeriodEnd: 18/04/2011 17:15:54
Count: 12902
Max: 23041 Min: 0
Mean: 102.86 StdDev: 560.97
},
{
PeriodStart: 18/04/2011 17:15:49 
PeriodEnd: 18/04/2011 17:20:54
Count: 10000
Max: 23041 Min: 0
Mean: 102.86 StdDev: 560.97
}... etc

Если я хочу запросить коллекцию для заданного диапазона дат (скажем, все документы за последние 24 часа), что даст мне простейшие операции запроса для этого?

Для дальнейшего уточнения требований:

  • Это для службы мониторинга приложений, поэтому строгий CAP / ACID не обязательно требуется
  • Производительность также не является основным фактором. Чтение / запись будет не более 10 с в секунду, что в любом случае может быть обработано СУБД
  • Желательно иметь возможность обрабатывать изменяющиеся схемы документов
  • Важна простота запроса списков / наборов (специальные запросы имеют преимущество)

Ответы [ 8 ]

6 голосов
/ 18 апреля 2011

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

Если вы используете CouchDB, вы можете создавать свои индексы, разбивая части вашей даты на массив. ([year, month, day, hour, minute, second, ...])

Ваша функция карты, вероятно, будет выглядеть следующим образом:

function (doc) {
    var date = new Date(doc.PeriodStart);
    emit([ date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes() ] , null]);
}

Чтобы выполнить любой запрос диапазона, вам нужно преобразовать время начала и окончания в одну и ту же структуру массива. Оттуда ваш запрос на просмотр будет иметь параметры с именами startkey и endkey. Они будут получать параметры массива для начала и конца соответственно.

Итак, чтобы найти документы, которые были запущены за последние 24 часа, вы должны отправить строку запроса, подобную этой, в дополнение к полному URI для самого представления:

// start: Apr 17, 2011 12:30pm ("24 hours ago")
// end:   Apr 18, 2011 12:30pm ("today")
startkey=[2011,04,17,12,30]&endkey=[2011,04,18,12,30]

Или, если вы хотите все с этого текущего года:

startkey=[2011]&endkey=[2011,{}]

Обратите внимание на {}. При использовании в качестве конечного ключа: [2011,{}] идентично [2012], когда представление сопоставляется. (любой формат будет работать)

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

1 голос
/ 26 апреля 2011

Я решил пока пойти с Монго.

Я обнаружил, что установка / развертывание были относительно простыми, а оболочка C # была адекватна тому, что мы пытаемся сделать (и в тех случаях, когда это не так, мы можем прибегнуть к запросам javascriptлегко).

1 голос
/ 24 апреля 2011

Мне кажется, что самый простой способ реализовать то, что вам нужно, это выполнить запрос диапазона в поисковой системе, подобной ElasticSearch .

Я, например, конечно, не хотел бы писать весь код карты / сокращения для CouchDB (потому что я делал это в прошлом).Кроме того, исходя из моего опыта (YMMV), запросы диапазона будут превосходить представления CouchDB и использовать намного меньше ресурсов для больших наборов данных.

Не говоря уже о том, что вы можете вычислять интересную статистику с помощью «гистограммы даты» «1012»* в ElasticSearch .

ElasticSearch не содержит схем, основан на JSON, поэтому вы сможете оценить его для своего случая в очень короткое время.

1 голос
/ 19 апреля 2011

[Обновление отредактировано, чтобы соответствовать редактированию исходного вопроса]

Краткий ответ, (почти) любой из них будет работать.

Базы данных BigTable - отличная платформа для служб мониторинга (анализ журналатак далее).Я предпочитаю Cassandra (семейства Super Column, вторичные индексы, атомный прирост в ближайшее время), но HBase будет работать и для вас.Структурируйте значение даты так, чтобы его лексикографический порядок совпадал с порядком дат.Строки фиксированной длины, следующие за форматом «ГГГГММДДЧЧммсс», прекрасно работают для этого.Если вы используете эту строку в качестве своего ключа, диапазон запросов будет очень простым для выполнения.

Обработка изменения схемы очень проста - просто добавьте больше столбцов в семейство столбцов.Их не нужно определять заранее.

Я, вероятно, не использовал бы графические базы данных для этой проблемы, поскольку это, вероятно, приведет к обходу связанного списка.Тем не менее, у меня нет большого опыта работы с базами данных графов, поэтому примите этот совет с недолгой солью.

[Обновление: кое-что не имеет значения, так как вопрос был отредактирован, но я продолжаюэто для потомков]
Это все вы делаете с этой базой данных?Большая проблема с выбором базы данных NoSQL заключается не в том, чтобы найти базу, которая бы хорошо поддерживала требование one .Проблема в том, чтобы найти тот, который хорошо поддерживает все ваших запросов.Кроме того, каковы ваши эксплуатационные требования?Можете ли вы принять одну точку отказа?Какие накладные расходы на установку / обслуживание вы готовы терпеть?Можете ли вы пожертвовать низкой задержкой для пакетных операций с высокой пропускной способностью или в режиме реального времени ваш концерт?

Надеюсь, это поможет!

0 голосов
/ 15 сентября 2013

Mongodb очень позитивен для запросов, я думаю, что это полезно, потому что имеет много функций. Я использую mongodb для определения расстояния GPS, текстового поиска и модели конвейера (включая агрегацию)

0 голосов
/ 01 мая 2011

Так как это помечено Redis, и никто не ответил на этот аспект, я собираюсь предложить решение для этого.

Шаг первый, храните свои документы под данным ключом redis, в виде хэша или, возможно, в виде строки JSON. Шаг второй, добавьте ключ redis (давайте назовем его DocID) в отсортированный набор с меткой времени, преобразованной в метку времени UNIX. Например, где r - это экземпляр подключения Redis в клиентской библиотеке Redis Python:

mydocs: Doc12 => [JSON-строка документа]

В Python: r.set ('mydocs: Doc12', JSONStringOfDocument)

timeindex: документы, DocID, отметка времени:

В Python: r.zadd ('timeindex: Documents', 'Doc12', отметка времени)

Фактически вы создаете индекс документов на основе меток времени UNIX.

Чтобы получить документы за определенный промежуток времени, вы используете zrange (или zrevrange , если вы хотите изменить порядок), чтобы получить список идентификаторов документов в этом окне. Затем вы можете получить документы из БД в обычном режиме. Сортированные наборы довольно быстро в Redis. Дополнительные преимущества заключаются в том, что вы можете выполнять операции с наборами, такие как «документы в этом окне, но не в этом окне», и даже автоматически сохранять результаты в Redis для последующего использования.

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

Надеюсь, это поможет кому-то использовать Redis для этого.

0 голосов
/ 18 апреля 2011

Этот вопрос объясняет, как запросить диапазон дат в CouchDB. Вам нужно, чтобы ваши данные были в лексикографически сортируемом состоянии во всех примерах, которые я видел.

0 голосов
/ 18 апреля 2011

То, что вы хотите, это то, что вам даст доступ к некоторому пространственному индексу. Большинство из них работают от B-деревьев и / или хэшей, ни один из которых не особенно хорош для пространственной индексации.

Теперь, если ваше определение «последних 24 часов» просто «начинается или заканчивается в течение последних 24 часов», тогда может быть найдено B-дерево (вы делаете два запроса, один на PeriodStart, а затем на PeriodEnd, оба находясь в пределах диапазона временного окна).

Но если PeriodStart to PeriodEnd длиннее временного окна, то ни один из них вам не поможет.

В любом случае, это то, что вы ищете.

...