I am trying to use the aggregation function to display info in a chart. For this example, a document in the collection looks like this (excluding unnecessary fields for this query):
{
'locid' : <someid>, #Reference to a city & state collection
'collat' : <dateobj>, #a date object when this entry was saved
'pid' : <someid>, #Reference to a person collection
'pos' : <int> #Value I am interested in matching with location & date
}
So I basically start with a pid. I use this as my first $match parameter to limit the amount of data that gets thrown into the pipeline.
array(
'$match' => array(
'pid' => new \MongoId($pid)
)
),
So now that I have selected the correct pid, I tell it I only want/need certain fields:
array(
'$project' => array(
'pos' => 1,
'collat' => 1,
'locid' => 1
)
),
The second match is to say I only care about these locations right now ($ids contains an array of locid):
array(
'$match' => array(
'locid' => array('$in' => $ids)
)
),
And finally, I am saying group all the returned documents by collat and locid
array(
'$group' => array(
'_id' => array(
'locid' => '$locid',
'collat' => '$collat'
)
)
)
While the query completes OK and returns data, I am not getting the pos field back, it is only returning the locid and collat.
Questions
- Isn’t that what
$projectis for? I use it to tell the driver what fields I want returned? - Once I get the
posfield returning as well, how can I tell the driver I only want the lowest value for eachlocid&collatcombo pair? So say there are two entries for that date, location, and person: 4 & 8. I only care aboutpos=4
My end goal is to create a line chart with the X-Axis as the dates (from collat) and the Y-Axis will be the pos field, and each line will plot individual locid data.
Here is the entire parameters being sent to the aggregation driver.
$ops = array(
array(
'$match' => array(
'pid' => new \MongoId($pid)
)
),
array(
'$project' => array(
'pos' => 1,
'collat' => 1,
'locid' => 1
)
),
array(
'$match' => array(
'locid' => array('$in' => $ids)
)
),
array(
'$group' => array(
'_id' => array(
'locid' => '$locid',
'collat' => '$collat'
)
)
)
);
$out = $myCollection->aggregate($ops);
Update This is the way I got it to group & return pos without throwing an error. I need to spot check it though to make sure it’s actually returning the correct values though.
array(
'$group' => array(
'_id' => array(
'locid' => '$locid',
'collat' => '$collat'
),
array('$min' => '$pos')
)
)
Aggregation query is like an SQL statement
group by. You are telling{$group}what field(s) you want to ‘GROUP BY’ but you are not telling it how you want to aggregate the grouped information.The
{$group}you want is probably something like: