1

I have a query that aggregates based on a collection of documents (tickets). It looks for tickets with a pre-defined DisplayLabel and any AssignedToPerson. It then averages the WorkingDuration of each person's tickets and organizes them into a document of objects, with each object including the AssignedToPerson and the average of their WorkingDuration. It then sorts them by the newly created key called WorkingDurationAvg.

It grabs its label from a list of distinct DisplayLabels from the Requests collection.

var label = db.Requests.distinct("DisplayLabel");

var raw = db.Requests.aggregate([
  {$match:{"DisplayLabel": (label[5]) }},
  {
      $group: 
           {
            _id: "$AssignedToPerson",
            WorkingDurationAvg : { $avg :  "$WorkingDuration" }
           }

      },
  {$project:{_id : 1, "WorkingDurationAvg": 1}},
  {$sort : {"WorkingDurationAvg":1 }}
])

This gets assigned to raw, therefore raw.result would return something like this:

{
    "0" : {
        "_id" : "Bob",
        "WorkingDurationAvg" : 50.0000000000000000
    },
    "1" : {
        "_id" : "Jim",
        "WorkingDurationAvg" : 75.0000000000000000
    }
}

I then loop through each of the objects in raw.result and append a score to an array object that has the matching label[5], into a predefined field called time, based on their position.

var count = raw.result.length;  

raw.result.forEach
(
  function()
  {for (var i = 0; i < 1000; i++)
db.test.update(
  { "name" : (raw.result[i]._id), "dogs.capname" : (label[5]) },
  {$set: {"dogs.$.time": (count - i) / count }},
print(raw.result[i]._id)
)})

This works. The problem I'm running into, if you look at the first code snippet, is that I'm manually calling the DisplayLabel array number (in this example, I'm calling the [5]th element of label). I also call this [5]th element in the third code snippet. I want to iterate through each value of label. Meaning the query will run using label[0], and then label[1], and then label[2], and so on...

Here's what I tried:

var label = db.Requests.distinct("DisplayLabel");

for (var x=0;x<100;x++){ //newly created for loop, goes up to 100

var raw = db.Requests.aggregate([
  {$match:{"DisplayLabel": (label[x]) }}, //[5] is changed to [x]
  {
      $group: 
           {
            _id: "$AssignedToPerson",
            WorkingDurationAvg : { $avg :  "$WorkingDuration" }
           }

      },
  {$project:{_id : 1, "WorkingDurationAvg": 1}},
  {$sort : {"WorkingDurationAvg":1 }}
])
// } <<-- A bracket here would return the same thing as entering "label[100]"
var count = raw.result.length;  

raw.result.forEach
(
  function()
  {for (var i = 0; i < 1000; i++)
db.test.update(
  { "name" : (raw.result[i]._id), "dogs.capname" : (label[x]) },
  {$set: {"dogs.$.time": (count - i) / count }},
)})
} // <<-- A bracket here returns the same thing as entering "label[0]"

See the notes for what the curly brackets ending the "for" loop do.

From what I can tell, the problem is JavaScript based and not Mongo based. With the curly bracket higher up, the aggregation runs 101 times, but only returns the [100]th value into the next function. With the curly bracket at the end, the function only runs once and returns the result with the [0]th value. So the function either runs 101 times and THEN passes that value, or it's a "one and done".

I've also tried using this answer's idea, but I can only get it to return the [100]th value using this method.

I know that I'm able to iterate through each raw.result because if I run this query as-is, but without everything below raw.result.forEach, I am able to print each iteration of raw.result. Adding the forEach limits me to the last iteratated item.

Community
  • 1
  • 1
mjoyce91
  • 316
  • 2
  • 19
  • Did you try passing x to the anonymous function as per the linked answer you referenced? – DaveStSomeWhere Jun 11 '15 at 05:02
  • @DaveCoast , here's what I tried: adding `(function (x) {` right below the initial `for` statement, changing all variables to `x`, and capping the parentheses and curly brackets off at the end. I then change the initial `for` statement to use `k`, and I call `(k)` before the very last curly bracket. This returns undefined values unless I revert the mentioned function back to being anonymous. – mjoyce91 Jun 11 '15 at 13:09

0 Answers0