0

I am on MongoDB 2.6.0, and I have a collection with documents like this:

{ "mid" : 1021, 
  "day" : 298,
  "data":[
  {"ts" : 1,"kwh" : 0.017},
  {"ts" : 2,"kwh" : 0.018},
  {"ts" : 3,"kwh" : 0.019},
  ... ] }

I would like to flatten the array elements into individual fields like this:

{ "mid" : 1021, 
  "day" : 298,
  "ts1" : 0.017,
  "ts2" : 0.018,
  "ts3" : 0.019,
  ...
}

This looks like it should be possible with the Aggregation framework, but I really can't figure out how to re-project the data array's "kwh" elements based on the value of "ts".

Anybody know how to do this?

Thanks for any help!

2
  • Are you sure you want to do this? Most queries will be a lot easier to do when you keep the data-array structure. Commented Jun 12, 2014 at 12:16
  • Possibly not being clear here. Do you actually want averages or something from the array data? Commented Jun 12, 2014 at 12:19

1 Answer 1

1

More of a mapReduce task really:

db.collection.mapReduce(
    function () {

      var copy = this;
      var tdata = copy.data;
      delete copy.data;

      tdata.forEach(function(data) {
        var key = "ts" + data.ts;
        copy[key] = data.kwh;
      });

      var id = copy._id;
      delete copy["_id"];

      emit( id, copy );

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

At present you cannot flexibly specify the value of a "key" using the aggregation framework. You wold have to explicitly name each key through projection in order to get the output you want.

MapReduce does not give "exactly" the same output as you want do to how it works. But it is the closest you will get without explicitly naming the keys.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.