2015-03-03 4 views
0

Я использую MongoDB 2.6.6Объединение MongoDB полей документов в один документ

У меня есть эти документы в коллекции MongoDB и здесь пример:

{ ..., "field3" : { "one" : [ ISODate("2014-03-18T05:47:33Z"),ISODate("2014-06-02T20:00:25Z") ] }, ...} 
{ ..., "field3" : { "two" : [ ISODate("2014-03-18T05:47:33Z"),ISODate("2014-06-02T20:00:25Z") ] }, ...} 
{ ..., "field3" : { "three" : [ ISODate("2014-03-18T05:47:39Z"),ISODate("2014-03-19T20:18:38Z") ] }, ... } 

Я хотел бы объединить эти документы в одном поле. Для примера, я хотел бы, чтобы новый результат будет следующим:

{ "field3", : { "all" : [ ISODate("2014-03-18T05:47:39Z"),ISODate("2014-03-19T20:18:38Z"),...... ] },} 

Я просто не уверен, что больше, как иметь такой результат! Любая помощь приветствуется. Спасибо.

+0

Это не очень хороший пример. У ваших документов действительно есть имена полей, которые всегда меняются, такие как «один», «два», «три» и т. Д., Как вы показываете? –

+0

Да, эти изменения. Я думал, что это было ясно, так как я назвал их по-разному, в то время как поле3 было одинаковым во всех документах. –

+0

Я спрашиваю, потому что это действительно не очень хорошая практика, и это делает операцию значительно более сложной, чем нужно было бы, если бы они были одинаковыми. Как бы вы тогда знали, «какие» из полей под полем 3 выбрать? И более того, какова цель именования, так как существует, возможно, лучший способ сделать то, что вы пытаетесь достичь. –

ответ

2

ли на самом деле не оставляет желать идти здесь, но вы можете возможно получить вид объединенного результата с MapReduce:

db.collection.mapReduce(
    function() { 
    var field = this.field3; 

    Object.keys(field).forEach(function(key) { 
     field[key].forEach(function(date) { 
     emit("field3", { "all": [date] }) 
     }); 
    }); 
    }, 
    function (key,values) { 

    var result = { "all": [] }; 

    values.forEach(function(value) { 
     value.all.forEach(function(date) { 
     result.all.push(date); 
     }); 
    }); 

    result.all.sort(function(a,b) { return a.valueOf()-b.valueOf() }); 

    return result; 

    }, 
    { "out": { "inline": 1 } } 
) 

Какого быть MapReduce не точно в том же формате вывод с учетом его собственного ограничения для ведения дел:

{ 
    "results" : [ 
      { 
        "_id" : "field3", 
        "value" : { 
          "all" : [ 
            ISODate("2014-03-18T05:47:33Z"), 
            ISODate("2014-03-18T05:47:33Z"), 
            ISODate("2014-03-18T05:47:39Z"), 
            ISODate("2014-03-19T20:18:38Z"), 
            ISODate("2014-06-02T20:00:25Z"), 
            ISODate("2014-06-02T20:00:25Z") 
          ] 
        } 
      } 
    ], 
    "timeMillis" : 86, 
    "counts" : { 
      "input" : 3, 
      "emit" : 6, 
      "reduce" : 1, 
      "output" : 1 
    }, 
    "ok" : 1 
} 

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

Во всяком случае, это будет полезно только относительно относительно небольшому набору данных с рядом с теми же ограничениями на обработку клиента. Больше, чем предел BSON на 16 МБ для MongoDB, но, конечно, ограничен памятью, которую нужно использовать.

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

Я бы лично пошел с кодом клиента здесь.

+0

Это действительно дало мне ошибку размера памяти. Спасибо за ваш ответ, но я решил использовать другой метод, используя фильтры Logstash для слияния этих полей. Я не тестировал ваш ответ на более мелкую коллекцию, поэтому я не уверен, что я должен проверить его как правильный ответ. Спасибо! –

+0

@ Issy. Часть точки, показывающая вам «как», что-то можно сделать, часто указывает на «почему это не должно быть так». Такой ответ звучит как окончательный ответ на меня. Действительно, нет другого способа сделать это помимо внешней обработки, как вы говорите, вы сделали, и это также будет страдать от подобных проблем памяти, если вы не фильтруете контент каким-то образом. –

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