Couchdb просмотров и многие (тысячи) типов документов - PullRequest
1 голос
/ 11 мая 2011

Я изучаю CouchDB и представляю худший сценарий:

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

Под "типом документа" я подразумеваю структуру документа.

После вставки нового документа, couchdb делает 3 * 10K вызовов для просмотра функций, ищущих нужный тип документа.

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

Пример документа (предположим, что ни один документ не имеет одинаковую структуру, в этом примере данные находятся под разными ключами):

[
     {
       "_id":"1251888780.0",
       "_rev":"1-582726400f3c9437259adef7888cbac0"
       "type":'sensorX',
       "value":{"ValueA":"123"}
     },
     {
       "_id":"1251888780.0",
       "_rev":"1-37259adef7888cbac06400f3c9458272"
       "type":'sensorY',
       "value":{"valueB":"456"}
     },
     {
       "_id":"1251888780.0",
       "_rev":"1-6400f3c945827237259adef7888cbac0"
       "type":'sensorZ',
       "value":{"valueC":"789"}
     },
   ]

Пример просмотров (в этом примере только один на тип документа)

  "views":
  {
    "sensorX": {
      "map": "function(doc) { if (doc.type == 'sensorX')  emit(null, doc.valueA) }"
    },
    "sensorY": {
      "map": "function(doc) { if (doc.type == 'sensorY')  emit(null, doc.valueB) }"
    },
    "sensorZ": {
      "map": "function(doc) { if (doc.type == 'sensorZ')  emit(null, doc.valueC) }"
    },
  }

Ответы [ 2 ]

5 голосов
/ 11 мая 2011

Результаты функции map() в CouchDB кэшируются при первом запросе представления для каждого нового документа. Позвольте мне объяснить с краткой иллюстрацией.

  • Вы вставляете 100 документов в CouchDB

  • Вы запрашиваете представление. Теперь для 100 документов запущена функция map(), и результаты кэшированы.

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

  • Вы добавляете еще 50 документов

  • Вы запрашиваете представление. 50 новых документов отображаются и объединяются в указатель со старыми 100 документами.

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

Надеюсь, это имеет смысл. Если вас беспокоит большая нагрузка, генерируемая, когда пользователь запрашивает представление, и добавлено много новых документов, вы можете посмотреть, как ваш процесс импорта вызывает представление (для повторного сопоставления новых документов) и запрос пользователя для просмотра включают stale=ok.

Книга CouchDB является действительно хорошим источником информации о CouchDB.

1 голос
/ 23 мая 2011

У Джеймса отличный ответ.

Похоже, вы задаете вопрос "Каковы значения документов типа X?"

Я думаю, что выможно сделать это с одним представлением:

function(doc) {
    // _view/sensor_value
    var val_names = { "sensorX": "valueA"
                    , "sensorY": "valueB"
                    , "sensorZ": "valueC"
                    };

    var value_name = val_names[doc.type];
    if(value_name) {
        // e.g. "sensorX" -> "123"
        // or "sensorZ" -> "789"
        emit(doc.type, doc.value[value_name]);
    }
}

Теперь, чтобы получить все значения для sensorY, вы запрашиваете /db/_design/app/_view/sensor_value с параметром ?key="sensorX".CouchDB покажет все значения для sensorX, которые получены из поля value.valueA документа.(Для датчика Y это value.valueB и т.быть лучше:

function(doc) {
     if(doc.type && doc.value) {
         emit(doc.type, doc.value);
     }
 }

Это очень просто, и любой документ будет работать, если у него есть поля type и value.Затем, чтобы получить valueA, valueB и т. Д., Просто сделайте это на стороне клиента.

Если использование клиента невозможно, используйте функцию _list.

function(head, req) {
    // _list/sensor_val
    //
    start({'headers':{'Content-Type':'application/json'}});

    // Updating this will *not* cause the map/reduce view to re-build.
    var val_names = { "sensorX": "valueA"
                    , "sensorY": "valueB"
                    , "sensorZ": "valueC"
                    };


    var row;
    var doc_type, val_name, doc_val;
    while(row = getRow()) {
        doc_type = row.key;
        val_name = val_names[doc_type];
        doc_val = row.value[val_name];
        send("Doc " + row.id + " is type " + doc_type + " and value " + doc_val);
    }
}

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

...