Mongodb MapReduce для объединения строк? - PullRequest
2 голосов
/ 04 июня 2010

Все примеры MongoDB MapReduce, которые я видел, касались подсчета / сложения чисел. Мне нужно объединить строки, и, похоже, MapReduce - лучший инструмент для работы. У меня есть большая коллекция MongoDB в этом формате:

{name: userone, type: typeone}
{name: usertwo, type: typetwo}
{name: userthree, type: typeone}

Каждое имя имеет только один тип, но имена не обязательно уникальны. Я хочу закончить коллекцией, в которой перечислены все имена для определенного типа, либо в списке через запятую, либо в массиве, например:

 {type: typeone, names: userone, usertwo}
 {type: typetwo, names: userthree}

Я пытался использовать MapReduce для достижения этой цели. Моя функция работает правильно, когда есть только один пользователь для типа. Однако, когда существует более одного пользователя, в поле имен хранится «undefined».

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

Вот моя карта и функции сокращения. Что с ними не так?

map = function() {
emit(this.user,{type:this.type});
}

reduce = function(key, values) {
var all="";
for(var i in values) {
all+=values[i]['type']+",";
}
return all;
}

1 Ответ

5 голосов
/ 04 июня 2010

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

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

Карта

m = function(){ emit(this.type, {names:this.name}); }

Снижение

r = function(key, values){
  var all = [];
  values.forEach(function(x){
    all.push(x.names)
  })
  return {"names": all.join(", ")};
}

Использование :

res = db.users.mapReduce(m,r); db[res.result].find()

Alternate:

Для каждого запроса OP, вот версия, которая возвращает массив имен вместо строки списка, разделенных запятыми:

m = function () {
    emit(this.type, {names:this.name});
}

r = function (key, values) {
    var all = [];
    values.forEach(function (x) {all.push(x.names);});
    return {type:key, names:all};
}

f = function (w, r) {
    r.names = r.names[0];
    return r
}

res = db.users.mapReduce(m,r, {finalize:f}); db[res.result].find()

Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...