Подтвердить что ты не робот

MongoDB карта/уменьшить количество нескольких коллекций?

Во-первых, фон. Раньше я имел коллекцию logs и использовал map/reduce для создания различных отчетов. Большинство из этих отчетов были основаны на данных за один день, поэтому у меня всегда было условие d: SOME_DATE. Когда коллекция logs стала чрезвычайно большой, вставка стала чрезвычайно медленной (медленнее, чем приложение, которое мы контролировали, создавало журналы), даже после того, как вы сбросили множество индексов. Поэтому мы решили иметь каждый день данные в отдельной коллекции - logs_YYYY-mm-dd - таким образом индексы меньше, и нам даже не нужен индекс на дату. Это здорово, так как большинство отчетов (таким образом, карта/сокращение) находятся на ежедневных данных. Тем не менее, у нас есть отчет, в котором мы должны охватывать несколько дней.

А теперь вопрос. Есть ли способ запустить карту/уменьшить (точнее, карту) по нескольким коллекциям, как если бы она была только одной?

4b9b3361

Ответ 1

Функция сокращения может вызываться один раз с ключом и всеми соответствующими значениями (но только если для ключа есть несколько значений - он вообще не будет вызываться, если только 1 значение для ключа).

Он также может быть вызван несколько раз, каждый раз с ключом и только подмножество соответствующих значений, а предыдущие уменьшают результаты для этого ключа. Этот сценарий называется re-reduce. Для поддержки повторного уменьшения ваша функция сокращения должна быть idempotent.

В функции уменьшения идемпотента есть две ключевые функции:

  • возвращаемое значение функции уменьшения должно быть в в том же формате, что и значения. Таким образом, если функция сокращения принимает массив строк, функция должна возвращать строку. Если он принимает объекты с несколькими свойствами, он должен вернуть объект, содержащий те же свойства. Это гарантирует, что функция не сломается, когда она вызывается с результатом предыдущего уменьшения.
  • Не делайте предположений на основе количества значений, которое требуется. Не гарантируется, что параметр values содержит все значения для данного ключа. Поэтому использование values.length в расчетах является очень рискованным и его следует избегать.

Обновление: Два нижеследующих шага не требуются (или даже возможно, я не проверял) в более поздних выпусках MongoDB. Теперь он может обрабатывать эти действия для вас, если вы укажете выходную коллекцию в map-reduce options:

{ out: { reduce: "tempResult" } }

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

Шаг 1

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

finalize = function (key, value) {
  db.tempResult.save({ _id: key, value: value });
}

db.someCollection.mapReduce(map, reduce, { finalize: finalize })
db.anotherCollection.mapReduce(map, reduce, { finalize: finalize })

Шаг 2

Запустите еще один снимок карты во временной коллекции , используя ту же функцию сокращения. Функция map - это простая функция, которая выбирает ключи и значения из временной коллекции:

map = function () {
  emit(this._id, this.value);
}

db.tempResult.mapReduce(map, reduce)

Этот второй снимок карты в основном редуцирует и должен дать вам нужные результаты.

Ответ 2

Я использовал метод map-reduce. вот пример.

var mapemployee = function () {
    emit(this.jobid,this.Name);};

var mapdesignation = function () {
    emit(this.jobid, this.Designation);};

var reduceF = function(key, values) {
    var outs = {Name:null,Designation: null};
    values.forEach(function(v){
    if(outs.Name ==null){
   outs.Name = v.Name }
   if(outs.Name ==null){
    outs.Nesignation = v.Designation}                    
     });
    return outs;
};

result = db.employee.mapReduce(mapemployee, reduceF, {out: {reduce: 'output'}});
result = db.designation.mapReduce(mapdesignation,reduceF, {out: {reduce: 'output'}});

Refference: http://www.itgo.me/a/x3559868501286872152/mongodb-join-two-collections