简体   繁体   中英

Merging MongoDB fields of documents into one document

I'm using MongoDB 2.6.6

I have these documents in a MongoDB collection and here is an example:

{ ..., "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") ] }, ... }

I would like the merge these documents in one field. For an example, I would like the new result to be as follows:

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

I'm just not sure any more how to have that result!

Doesn't really leave much to go on here but you can arguably get the kind of merged result with 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 } }
)

Which being mapReduce is not exactly in the same output format given it's own restrictions for doing things:

{
    "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
}

Since the aggregation here into a single document is fairly arbitrary you could pretty much argue that you simply take the same kind of approach in client code.

At any rate this is only going to be useful over a relatively small set of data with next to the same sort of restrictions on the client processing. More than the 16MB BSON limit for MongoDB, but certainly limited by memory to be consumed.

So I presume you would need to add a "query" argument but it's not really clear from your question. Either using mapReduce or your client code, you are basically going to need to follow this sort of process to "mash" the arrays together.

I would personally go with the client code here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM