Skip to content

Commit d0808aa

Browse files
dplewismontymxb
authored andcommitted
Support for Aggregate Queries (#355)
* Support for Aggregate Queries * lint!!! * nit and tests on user class * fixed tests * flaky test * clean up * documentation
1 parent af27c70 commit d0808aa

File tree

3 files changed

+395
-5
lines changed

3 files changed

+395
-5
lines changed

README.md

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ from your PHP app or script. Designed to work with the self-hosted Parse Server
2323
- [Users](#users)
2424
- [ACLs/Security](#acls)
2525
- [Queries](#queries)
26+
- [Aggregate](#aggregate)
27+
- [Distinct](#distinct)
2628
- [Relative Time](#relative-time)
2729
- [Cloud Functions](#cloud-functions)
2830
- [Cloud Jobs](#cloud-jobs)
@@ -42,7 +44,7 @@ from your PHP app or script. Designed to work with the self-hosted Parse Server
4244
- [Contributing / Testing](#contributing--testing)
4345

4446
## Installation
45-
There are various ways to install and use this sdk. We'll elaborate on a couple here.
47+
There are various ways to install and use this sdk. We'll elaborate on a couple here.
4648
Note that the Parse PHP SDK requires PHP 5.4 or newer.
4749

4850
### Install with Composer
@@ -224,7 +226,7 @@ use Parse\ParseAudience;
224226
### Parse Objects
225227

226228
Parse Objects hold your data, can be saved, queried for, serialized and more!
227-
Objects are at the core of this sdk, they allow you to persist your data from php without having to worry about any databasing code.
229+
Objects are at the core of this sdk, they allow you to persist your data from php without having to worry about any databasing code.
228230

229231
```php
230232
$object = ParseObject::create("TestObject");
@@ -254,7 +256,7 @@ $decodedObject = ParseObject::decode($encoded);
254256

255257
### Users
256258

257-
Users are a special kind of object.
259+
Users are a special kind of object.
258260
This class allows individuals to access your applications with their unique information and allows you to identify them distinctly.
259261
Users may also be linked with 3rd party accounts such as facebook, twitter, etc.
260262

@@ -302,7 +304,7 @@ $acl->setRoleWriteAccessWithName("PHPFans", true);
302304

303305
### Queries
304306

305-
Queries allow you to recall objects that you've saved to parse-server.
307+
Queries allow you to recall objects that you've saved to parse-server.
306308
Query methods and parameters allow allow a varying degree of querying for objects, from all objects of a class to objects created within a particular date range and more.
307309

308310
```php
@@ -327,6 +329,59 @@ $first = $query->first();
327329
$query->each(function($obj) {
328330
echo $obj->getObjectId();
329331
});
332+
333+
```
334+
#### Aggregate
335+
336+
Queries can be made using aggregates, allowing you to retrieve objects over a set of input values.
337+
Keep in mind that `_id` does not exist in parse-server. Please replace with `objectId`. MasterKey is Required
338+
339+
For a list of available operators please refer to Mongo Aggregate Documentation.
340+
341+
<a href="https://docs.mongodb.com/v3.2/reference/operator/aggregation/">Mongo 3.2 Aggregate Operators</a>
342+
343+
```php
344+
// group pipeline is similar to distinct, can apply $sum, $avg, $max, $min
345+
// accumulate sum and store in total field
346+
$pipeline = [
347+
'group' => [
348+
'objectId' => null,
349+
'total' => [ '$sum' => '$score']
350+
]
351+
];
352+
$results = $query->aggregate($pipeline);
353+
354+
// project pipeline is similar to keys, add or remove existing fields
355+
// includes name key
356+
$pipeline = [
357+
'project' => [
358+
'name' => 1
359+
]
360+
];
361+
$results = $query->aggregate($pipeline);
362+
363+
// match pipeline is similar to equalTo
364+
// filter out objects with score greater than 15
365+
$pipeline = [
366+
'match' => [
367+
'score' => [ '$gt' => 15 ]
368+
]
369+
];
370+
$results = $query->aggregate($pipeline);
371+
```
372+
373+
#### Distinct
374+
375+
Queries can be made using distinct, allowing you find unique values for a specified field.
376+
Keep in mind that MasterKey is required.
377+
```php
378+
// finds score that are unique
379+
$results = $query->distinct('score');
380+
381+
// can be used with equalTo
382+
$query = new ParseQuery('TestObject');
383+
$query->equalTo('name', 'foo');
384+
$results = $query->distinct('score');
330385
```
331386

332387
#### Relative Time
@@ -557,7 +612,7 @@ $globalConfigFeatures = ParseServerInfo::getGlobalConfigFeatures();
557612
* "delete" : true
558613
* }
559614
*/
560-
615+
561616
// you can always get all feature data
562617
$data = ParseServerInfo::getFeatures();
563618
```

src/Parse/ParseQuery.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,65 @@ public function count($useMasterKey = false)
519519
return $result['count'];
520520
}
521521

522+
/**
523+
* Execute a distinct query and return unique values.
524+
*
525+
* @param string $key field to find distinct values
526+
*
527+
* @return array
528+
*/
529+
public function distinct($key)
530+
{
531+
$sessionToken = null;
532+
if ($user = ParseUser::getCurrentUser()) {
533+
$sessionToken = $user->getSessionToken();
534+
}
535+
$opts = [];
536+
if (!empty($this->where)) {
537+
$opts['where'] = $this->where;
538+
}
539+
$opts['distinct'] = $key;
540+
$queryString = $this->buildQueryString($opts);
541+
$result = ParseClient::_request(
542+
'GET',
543+
'aggregate/'.$this->className.'?'.$queryString,
544+
$sessionToken,
545+
null,
546+
true
547+
);
548+
549+
return $result['results'];
550+
}
551+
552+
/**
553+
* Execute an aggregate query and returns aggregate results.
554+
*
555+
* @param array $pipeline stages to process query
556+
*
557+
* @return array
558+
*/
559+
public function aggregate($pipeline)
560+
{
561+
$sessionToken = null;
562+
if ($user = ParseUser::getCurrentUser()) {
563+
$sessionToken = $user->getSessionToken();
564+
}
565+
$stages = [];
566+
foreach ($pipeline as $stage => $value) {
567+
$stages[$stage] = json_encode($value);
568+
}
569+
$queryString = $this->buildQueryString($stages);
570+
$result = ParseClient::_request(
571+
'GET',
572+
'aggregate/'.$this->className.'?'.$queryString,
573+
$sessionToken,
574+
null,
575+
true
576+
);
577+
578+
return $result['results'];
579+
}
580+
522581
/**
523582
* Execute a find query and return the results.
524583
*

0 commit comments

Comments
 (0)