Custom Couchbase уменьшить, чтобы подсчитать только некоторые значения

Имея следующую карту:

function (doc, meta) {
  emit(dateToArray(doc.timestamp), doc.user_id);
}

Какие изменения мне нужно внести в это сокращение, чтобы получить user_ids, которые происходят более одного раза?

function(key, values, rereduce) {
  var counts = {}, id;
  for (var i = 0; i < values.length; i++) {
    id = values[i].replace('-', '_');
    counts[id] = counts[id] || 0;
    counts[id] = counts[id] + 1;
  }
  var total = 0;
  for (id in counts) {
    if (counts[id] > 1) total++;
  }
  return total;
}

Я пробовал это на простом JS, передавая некоторый массив значений, и он работает так, как я ожидал. Однако отладка на Couchbase затруднена (или я не знаю как), и я не вижу никаких ошибок в файлах error.1 и mapreduce_errors.1.

Обновление: я проделал некоторую грубую отладку построчно, и вот что у меня есть:

function(key, values, rereduce) {
  var counts = {}, total = 0;
  for (var i = 0; i < values.length; i++) {
    var id = values[i];
    if (id.indexOf('id_') != 0) id = 'id_' + values[i].replace(/-/g, '_');
    return id;
    counts[id] = counts[id] || 0;
    counts[id] = counts[id] + 1;
  }
  for (id in counts) {
    if (counts[id] > 1) total++;
  }
  return total;
}

Обратите внимание на строку return id;. Он возвращает измененный uuid с префиксом id_, как и следовало ожидать, глядя на код.

Но затем, если я изменю эту строку на return counts; или return total;, результатом Couchbase будет «Результаты этого представления пусты». Что дает?


person Ivan    schedule 09.06.2014    source источник


Ответы (1)


Это был один болезненный сеанс отладки, но вот окончательное решение:

function(key, values, rereduce) {
  var counts = {}, total = 0, id;
  if (rereduce) {
    for (var set in values) {
      for (var i in values[set]) {
        counts[i] = (counts[i] || 0) + values[set][i];
      }
    }
    for (f in counts) {
      if (counts[f] > 1) total++;
    }
    return total;
  } else {
    for (var i in values) {
      id = 'id_' + values[i].replace(/-/g, '_');
      counts[id] = (counts[id] || 0) + 1;
    }
    return counts;
  }
}

Еще один усвоенный урок: Couchbase не возвращает большие объекты из операции сокращения. Надо узнать об этом больше.

person Ivan    schedule 10.06.2014
comment
Обратите внимание, что существует параметр debug = true, который можно передать в запрос представления, который будет регистрировать дополнительную информацию как на уровне ns_server, так и на уровне выполнения отдельного представления. Если у вас есть тест, который показывает, что вы имеете в виду при операции сокращения, было бы здорово подать его на couchbase.com/issues. - person Matt Ingenthron; 11.06.2014
comment
: facepalm: этот параметр есть прямо в админке, и я не подумал включить его, спасибо. У меня нет теста, я просто попытался вернуть объект counts вместо total для целей отладки, и это не сработало, и из вариантов, которые я пробовал, казалось, что это было вызвано размером объекта: { 'id_abc...': 1, 'id_xyz...': 2, ... } всего с сотнями ключей. - person Ivan; 11.06.2014