CouchDB Modeling - время фильтруется и группирует данные - PullRequest
3 голосов
/ 09 февраля 2012

Я пытаюсь углубить свое понимание CouchDB и того, как моделировать данные для некоторых реальных сценариев.Я сделал столько, сколько смогу, «покажи мне сообщения в блоге по дате»;)

Имеются такие документы:

{
    "_id": "couch1",
    "_rev": "2-338d0a592ad1e5570000002b00000000",
    "eventType": "event1",
    "date": 1328805860000
}

{
    "_id": "couch2",
    "_rev": "1-1e0315c2e1ca7f5f0000002b00000000",
    "eventType": "event1",
    "date": 1328133600000
}

{
    "_id": "couch3",
    "_rev": "1-154cd416b78cb2ef0000002b00000000",
    "eventType": "event2",
    "date": 1325434920000
}

Где дата - эпохаМожно ли попросить Кауча сделать представление, где вы запрашивали все «события», произошедшие между двумя метками времени, а затем сгруппировать эти данные по «eventType»?

Итак, используя вышеизложенное и предполагаяпереданные метки времени охватывают эти документы - мы бы хотели видеть вывод:

"event1": 2
"event2": 1

Дополнительная информация, которую я получил

Я знаю, что Couch будет сортироватьпо ключу, так что если бы я хотел получить «топ-10», то это был бы второй этап, но я справлюсь с этим.

Итак, основная проблема здесь в том, что вы фильтруете по одному столбцу, а затем группируете по другому?

Если мы используем следующую функцию карты:

function (doc) {
  emit([doc.date, doc.eventType], doc.eventType);
}

с функцией уменьшения count, мы видим, что, поскольку временные метки по сути уникальны, Couch не может группировать, а ключ имеет значение 1.

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

function (doc) {
  emit([doc.eventType, doc.date], doc.eventType);
}

А затем измените group level на 1, который будет сгруппирован правильно по событию, но ваши данные не могут быть разрезаны по времени, потому что ваш основной порядок - по имени события, то есть порядок временисейчас сломан?

Есть ли у людей какие-либо военные истории по этому поводу?Нужно ли это делать с помощью повторного уменьшения?

Большое спасибо всем, кто нашел время, чтобы прочитать это

Яйцо

Ответы [ 3 ]

1 голос
/ 10 февраля 2012

Я бы предложил вид / список Combo:

Вид:

"eventByDate": 
{
  "map": "function(doc) { emit(doc.date, doc.eventType);}"
}

Список:

"test": "function(head,req) {
  var eventO=new Object();
  while(row=getRow()) {
  if(eventO[row.value]==undefined) {
    eventO[row.value]=1;
  }else{
    eventO[row.value]++;
  }
 }
 send("[");
 for (var curEvent in eventO) {
  send ("{\"event\":\""+curEvent +"\",\"count\":"+eventO[curEvent]+"}");
 }
 send("]");
}"

Результат:

[
{"event":"event2","count":1} 
{"event":"event1","count":2} 
]

Но вы должны сделать заказ вручную (я не реализовал это) здесь или в вашем бэкэнде

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

Вы можете сделать, как показывает @ user791770, но вам не нужно жестко кодировать список типов событий, слегка изменив код.

Карта:

function(doc) {
  var data = {};
  data[doc.type] = 1;
  emit(doc.time, data);
}

Сокращение:

function(keys, values, rereduce) {
  var data = {};
  for ( i = 0; i < values.length; i++) {
    for (var field in values[i]) {
      if (typeof data[field] == 'undefined') data[field] = 0;
      data[field] += values[i][field];
    }
  }
  return data;
}
0 голосов
/ 10 февраля 2012

У вас есть фиксированное количество типов событий?Это небольшой, относительно статичный список?

Если нет, пропустите оставшуюся часть моего ответа.

Если это так, читайте дальше для быстрого и грязного варианта.

Выможет изменить вашу функцию map.js, чтобы иметь несколько функций emit (), основанных на значении типа события.

if(eventType == event1 ) {emit(doc.date, {'eventType1': 1} 

Повторение для каждого типа события.Или, если вы можете изменить свои документы таким образом, чтобы поля eventType1, eventType2 и т. Д. Представляли собой поля со значением 1, вы можете пропустить все причудливые if ... then бессмыслица и просто:

emit(doc.date, doc).

ТогдаСделайте так, чтобы ваша функция redu.js перебирала строки и добавляла их к объекту, который в конечном итоге выглядел бы примерно так:

{eventType1: 25, eventType2: 2, ...}

for ( i = 0; i < values.length; i++){
    if ( values[i].eventType1 > 0) { eventType1 += 1 }
    if ( values[i].eventType2 > 0) { eventType2 += 1 }
    ...
}   

Запросите это представление без group или group = false, и вы должны получить единственную запись с нулевым ключом с вашими типами событий и их счетами.

Я работаю над запросом аналогичного типа.Но мой список "eventType" никогда не меняется.

...