Nano Hash - криптовалюты, майнинг, программирование

Как сгруппировать документы, сопоставив элементы массива с 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 может вызывать функцию сокращения более одного раза для одного и того же ключа. В этом случае предыдущий вывод функции сокращения для этого ключа станет одним из входных значений для следующего вызова функции сокращения для этого ключа.

...что приводит к вложенным объектам результатов. Как правильно сгруппировать документы по их совпадению?


Ответы:


1

вызывать функцию сокращения более одного раза для одного и того же ключа.

Это idempotence, и функция сокращения должна это учитывать.

Но, чтобы сделать это простым, вам просто нужно убедиться, что выходные данные карты имеют тот же формат, что и уменьшенный.

В вашем случае будет работать что-то вроде этого:

db.col.insert({"name": "Ash", "words": ["Apple", "Pear", "Plum"]})
db.col.insert({"name": "Joe", "words": ["Walnut", "Peanut"]})
db.col.insert({"name": "Max", "words": ["Pineapple", "Apple", "Plum"]})

function map() {

    input = ["Walnut", "Peanut", "Apple"]

    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, {users: [{name: this.name, match: key}]});
}

function reduce(key, value) {

    ret = value[0]

    for(var i=1; i<value.length; i++){
        ret.users = ret.users.concat(value[i].users)
    }

    return ret

}

db.col.mapReduce(map, reduce, {"out": {inline:1}})

Выход:

{
    "results" : [
        {
            "_id" : "0.33",
            "value" : {
                "users" : [
                    {
                        "name" : "Ash",
                        "match" : "0.33"
                    },
                    {
                        "name" : "Max",
                        "match" : "0.33"
                    }
                ]
            }
        },
        {
            "_id" : "0.67",
            "value" : {
                "users" : [
                    {
                        "name" : "Joe",
                        "match" : "0.67"
                    }
                ]
            }
        }
    ],
    "timeMillis" : 22,
    "counts" : {
        "input" : 3,
        "emit" : 3,
        "reduce" : 1,
        "output" : 2
    },
    "ok" : 1
}
20.09.2016
  • Спасибо, это было именно то, что я был после. Очень полезный ответ! 20.09.2016
  • Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..