2015-07-09 6 views
1

С документами, как:MongoDB Map Сокращение на полях объекта

{ 
    _id: 123, 
    events: { 
     someEvent:{ 
      created: ISODate("2015-06-27T16:51:03.000Z"), 
      metadata: { 
       some: "thing" 
      } 
     }, 
     anotherEvent:{ 
      created: ISODate("2015-06-27T16:51:01.000Z"), 
      metadata: { 
       some: "thing" 
      } 
     } 
    } 
} 

Это упрощенный пример данных. Объект событий может иметь от 200 до 3000 полей. Есть тысячи таких документов.

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

Возможно ли это?

ответ

2

Да, это возможно. MapReduce немного о «тупой меч» для этого, но ваша структура элемент «не велик» и возможный 3000 элементов нужно что-то вроде этого:

db.collection.mapReduce(
    function() { 
     var doc = this; 
     var plucked = Object.keys(doc.events) 
      .map(function(key) { 
       var myObj = doc.events[key]; 
       myObj.key = key; 
       return myObj; 
      }) 
      .sort(function(a,b) { 
       return (a.created > b.created) 
        ? -1 : (a.created < b.created) 
        ? 1 : 0; 
      })[0]; 

     emit(this._id, plucked); 
    }, 
    function() {}, 
    { "out": { "inline": 1 } } 
); 

Так в основном, что cylces хотя «события» и перестраивает данные несколько. Затем вы получите .sort() на «созданную» клавишу результатов в «порядке декодирования» и просто вытащите первый элемент массива.

«Редуктор» здесь ничего не делает. Но это всего лишь способ для сервера выполнить фильтрацию.

+0

Замените эти две ссылки «obj» на «doc», и это победитель! – Drew

+0

@Drew Так плохо меня. Это научит меня вырезать/вставить из ссылочного счёта, над которым я работаю. Исправлено. Хороший улов –

Смежные вопросы