简体   繁体   中英

How to create object from array elements to be passed into mongodb aggregation in mongoose and node.js?

I've a usecase in which I'll get dynamic field names in an array. I need to pass those fields to the mongo db aggregation query to get the sum of that field values in a given month. I need to remove the timeStamp & deviceId fields in array.

let jsonObj = [
  { name: "heat", value: "HEAT" },
  { name: "humidity", value: "HUMIDITY" },
  { name: "deviceId", value: "DEVICEID" },
  { name: "timeStamp", value: "TIMESTAMP" }
];

let vList = [];
jsonObj.forEach(async data => {
  if (!data.name.match(/time/g) || !data.name.match(/deviceId/g)) {
    vList.push(data.name); //Should exclude timestamp & deviceId (case-insensitive)
  }
});

let variableObj = [];
vList.forEach(async data => {
  let k = "{" + '"$sum":"$' + data + '"}';
  // console.log(k)
  k = JSON.parse(k);
  variableObj.push(data + ":" + k);
});

Then resultant array looks like the following.

[ 'heat:{"$sum":"$heat"}',
  'humidity:{"$sum":"$humidity"}',
  'timeStamp:{"$sum":"$timeStamp"}',
  'deviceId:{"$sum":"$deviceId"}' ]

Am not getting how to remove the single quotes around each item and how to pass them to query.

My query is:

db.collection(templateId).aggregate([
  {
    $match: {
      entryDayTime: {
        $lt: new Date(lastDay),
        $gte: new Date(firstDay)
      }
    }
  },
  {
    $group: {
      _id: "$deviceId",
      Count: { $sum: 1 }
      // Should pass those array elements here like,
      //heat:{"$sum":"$heat"},
      //humidity:{"$sum":"$humidity"}
    }
  },
  { $sort: { entryDayTime: -1 } }
]);

This should work.

 const jsonObj = [ { name: "heat", value: "HEAT" }, { name: "humidity", value: "HUMIDITY" }, { name: "deviceId", value: "DEVICEID" }, { name: "timeStamp", value: "TIMESTAMP" } ]; const filteredJson = jsonObj.filter(i => i.name !== "deviceId" && i.name !== "timeStamp"); const groupQuery = { $group:{ _id:"$deviceId", Count:{$sum:1} } }; filteredJson.forEach(row => { groupQuery.$group[row.name] = {"$sum": `$${row.name}`}; }); console.log(groupQuery);

Hope this helps. All you need to do is now, insert the $group with the variable prepared above.

You could create the whole group object together and pass it onto the $group stage. Also remove those async keywords, the iterations are not asynchronous.

Note: The if clause should have && to exclude both keywords and i flag is for case-insensitivity in regex. And creation of the target object can be completed in the first iteration itself.

 let jsonObj = [ { name: "heat", value: "HEAT" }, { name: "humidity", value: "HUMIDITY" }, { name: "deviceId", value: "DEVICEID" }, { name: "timeStamp", value: "TIMESTAMP" } ]; let groupObject = { _id: "$deviceId", Count: { $sum: 1 } }; jsonObj.forEach(data => { if (!data.name.match(/timestamp/gi) && !data.name.match(/deviceid/gi)) { groupObject[data.name] = { $sum: "$" + data.name }; } }); console.log(groupObject);

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