У меня есть база данных с столбцом, содержащим массив строк. Пример таблицы:Как сгруппировать документы, сопоставляя элементы массива с MapReduce в MongoDB?
name | words | ...
Ash | ["Apple", "Pear", "Plum"] | ...
Joe | ["Walnut", "Peanut"] | ...
Max | ["Pineapple", "Apple", "Plum"] | ...
Теперь я хотел бы, чтобы соответствовать этой таблице против данного массива слов и группировать документы по скорости их согласования.
Пример входных данных с ожидаемым результатом:
// matched for input = ["Walnut", "Peanut", "Apple"]
{
"1.00": [{name:"Joe", match:"1.00"}],
"0.33": [{name:"Ash", match:"0.33"}, {name:"Max", match:"0.33"}]
}
Я использую следующую map
функцию, испускающий документ со скоростью согласования в качестве ключа:
function map() {
var matches = 0.0;
for(var i in input)
if(this.words.indexOf(input[i]) !== -1) matches+=1;
matches /= input.length;
var key = ""+matches.toFixed(2);
emit(key, {name: this.name, match: key});
}
Теперь недостающего является соответствие reduce
функция объединить излучаемые пары KV в объект результата.
Я пробовал так:
function reduce(key, value) {
var res = {};
res[key] = values;
return res;
}
Однако у меня есть проблемы с уточнением, что
MongoDB может вызвать функцию уменьшения более чем один раз для одной и той же ключа. В этом случае предыдущий вывод функции уменьшения для , что ключ станет одним из входных значений для следующего уменьшения функции вызова для этого ключа.
... в результате чего возникают объекты вложенных результатов. Каков правильный способ группировки документов по их совпадению?
Спасибо, это было именно то, что я был после. Очень полезный ответ! – Appleshell