Функция уменьшения Couchdb возвращает только сумму (значение), которая соответствует определенным условиям


Я новичок в Couchdb, и в настоящее время я застрял в небольшой (вероятно...) проблеме с использованием функции map-reduce в CouchDB, и поскольку я не могу найти соответствующую информацию в Интернете. Я хотел бы попросить помощи здесь для себя.
В основном сценарий таков: я использую функцию карты для подсчета количества раз определенного слова, которое появляется в определенном документе. И сделайте излучение просто так:

emit(word,1)

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

function(key, values, rereduce)
{
    return sum(values);
}

Но мне действительно нужно возвращать только сумму (значения), превышающую 3000 (чтобы узнать слово, которое появляется более 3000 раз во всех документах). Поэтому я пытаюсь сделать так:

function(key, values, rereduce)
{
    if(sum(values)>3000)
    return sum(values);
}

Но таким образом все слова, встречающиеся менее 3000 раз, все равно будут возвращены, но со значением null. Я знаю, что это потому, что функция сокращения должна что-то возвращать, поэтому, когда оператор «если» не соответствует, вместо этого он должен возвращать ноль. Но есть ли кто-нибудь, кто мог бы дать мне полезное предложение по этому поводу - как вернуть сумму (значения), которая соответствует только определенным условиям...


person jinnancun    schedule 04.05.2014    source источник


Ответы (1)


Вероятно, невозможно

Я не думаю, что то, что вы пытаетесь сделать, возможно. Все, что делает функция сокращения, - это агрегировать/суммировать количество слов в нескольких документах с одним и тем же ключом, она всегда будет возвращать что-то для всех ключей, которые вы сгенерировали в своей функции карты.

Рассмотрите возможность уменьшения/уменьшения

Даже если вы можете принять код с нулевым значением, у вас есть потенциальная ошибка. Прочтите: https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Reduce_vs_rereduce

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

Если только эти сегменты (размером которых управляет Couchdb) не превышают 3000 элементов, ваш запрос, скорее всего, будет означать, что вы будете генерировать много «нулевых» значений, а затем будете их повторно уменьшать. Если что-то, что ваш код должен читать:

    function(key, values, rereduce)
    {
        if(rereduce && sum(values)<3000){return 0;}
        return sum(values);
    }

Альтернативная установка

Я предполагаю, что у вас слишком много слов в ваших документах, чтобы вы могли запросить их все. Я бы проверил, можете ли вы использовать части слова в качестве ключа, например, если у вас есть слово «диван» и «couchdb», вы бы выдали их как часть документа с ключом «co» или «cou " и тому подобное

    { "couch" :  1, "couchdb" : 15 } 

У вас по-прежнему будет ограниченное количество ключей, которые вы можете проанализировать и применить правило 3000 к повторному сокращению. Однако вы рискуете нарушить следующее эмпирическое правило относительно размера значений после вызова сокращения:

https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#reduced_value_sizes

Отказ от ответственности

Для типа проблемы полнотекстового поиска вы можете взглянуть на Couchdb-lucene. (Я не использовал его, поэтому не знаю, сможете ли вы решить свою проблему.)

person Hans    schedule 04.05.2014
comment
Ваше объяснение очень ясно. Большое спасибо за вашу помощь, и мне удалось решить эту проблему. Спасибо - person jinnancun; 03.10.2014
comment
@jinnancun - можете поделиться, как вы решили проблему? - person CarCrazyBen; 31.08.2017