'Return an array element of an aggregation in an MongoDB Atlas (4.2) trigger function

So I am currently testing with returning an array element of a an aggregation in an MongoDB Atlas (4.2) trigger function:

  exports = function(changeEvent) {

    const collection = context.services.get(<clusterName>).db(<dbName>).collection(<collectionName>);

    var aggArr = collection.aggregate([
      { 
        $match: { "docType": "record" }
      },
      ..,
      {
        $group: {
          "_id": null,
          "avgPrice": {
            $avg: "$myAvgPriceFd"
          }
        }
      }
    ]);

    return aggArr;

  };

Which outputs:

  > result:
  [
  {
    "_id": null,
    "avgPrice": {
      "$numberDouble": "18.08770081782988165"
    }
  }
  ]
  > result (JavaScript):
    EJSON.parse('[{"_id":null,"avgPrice":{"$numberDouble":"18.08770081782988165"}}]')

As you can see this is returned as one object in an array (I then intend to use the avgPrice value to update a field in a document in the same collection). I have tried to extract the object from the array with aggArr[0] or aggArr(0) - both resulting in:

  > result: 
  {
    "$undefined": true
  }
  > result (JavaScript): 
  EJSON.parse('{"$undefined":true}')

or by using aggArr[0].avgPrice as per this solution which fails with:

  > error: 
  TypeError: Cannot access member 'avgPrice' of undefined
  > trace: 
  TypeError: Cannot access member 'avgPrice' of undefined
      at exports (function.js:81:10(163))
      at function_wrapper.js:5:30(18)
      at <eval>:13:8(6)
      at <eval>:2:15(6)

Any pointers are most welcome because this one has me stumped for now!



Solution 1:[1]

I had the same problem, and figured it out. You have to append the .toArray() function to the aggregation call, where you have. collection.aggregate(pipeline_steps).toArray()

Here's an example:

  const user_collection = context.services
  .get("mongodb-atlas")
  .db("Development")
  .collection("users");

  const search_params = [
      {
        "$search": {
          "index": 'search_users',
          "text": {
            "query": value,
            "path": [
              "email", "first_name", "last_name"
            ],
            "fuzzy":{
              "prefixLength": 1,
              "maxEdits": 2
            }
          }
        }
      }
  ];
      
const search_results = await user_collection.aggregate(search_params).toArray();
const results = search_results
return results[0]

Here's the documentation showing how to convert the aggregation to an array.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Arky Asmal