Skip to content

Commit 3e5e267

Browse files
author
Erwan Richard
committed
Initial Release
1 parent 263d000 commit 3e5e267

16 files changed

+718
-0
lines changed

Diff for: README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
ElasticSearch Query Builder
2+
===========================
3+
4+
This is a PHP library which helps you build query for an ElasticSearch client by using a fluent interface.
5+
6+
Installation
7+
------------
8+
9+
```
10+
$ composer require erichard/elasticsearch-query-builder
11+
```
12+
13+
Usage
14+
-----
15+
16+
```
17+
18+
use Erichard\ElasticQueryBuilder\QueryBuilder;
19+
use Erichard\ElasticQueryBuilder\Aggregation\Aggregation;
20+
use Erichard\ElasticQueryBuilder\Filter\Filter;
21+
22+
$qb = new QueryBuilder();
23+
24+
$qb
25+
->setType('my_type')
26+
->setIndex('app')
27+
->setSize(10)
28+
;
29+
30+
// Add an aggregation
31+
$qb->addAggregation(Aggregation::terms('agg_name')->setField('my_field'));
32+
33+
// Add a filter
34+
$boolFilter = Filter::bool();
35+
$boolFilter->addFilter(Filter::terms()->setField('field')->setValue($value));
36+
37+
38+
$qb->addFilter($boolFilter);
39+
40+
// I am using a client from elasticsearch/elasticsearch here
41+
$results = $client->search($qb->getQuery());
42+
43+
```

Diff for: composer.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "erichard/elasticsearch-query-builder",
3+
"license": "MIT",
4+
"type": "library",
5+
"description": "Create elastic search query with a fluent interface",
6+
"authors": [
7+
{
8+
"name": "Erwan Richard",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"autoload": {
13+
"psr-4": { "Erichard\\ElasticQueryBuilder\\": "src/" }
14+
},
15+
"require": {
16+
"php": ">=7.0"
17+
}
18+
}

Diff for: src/Aggregation/Aggregation.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Aggregation;
4+
5+
abstract class Aggregation
6+
{
7+
private $name;
8+
9+
public function __construct($name = null)
10+
{
11+
$this->name = $name;
12+
}
13+
14+
public function getName()
15+
{
16+
return $this->name;
17+
}
18+
19+
abstract public function build(): array;
20+
21+
public static function terms($name = null)
22+
{
23+
return new TermsAggregation($name);
24+
}
25+
26+
public static function nested($name = null)
27+
{
28+
return new NestedAggregation($name);
29+
}
30+
31+
public static function filter($name = null)
32+
{
33+
return new FilterAggregation($name);
34+
}
35+
}

Diff for: src/Aggregation/FilterAggregation.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Aggregation;
4+
5+
use Erichard\ElasticQueryBuilder\Filter\Filter;
6+
7+
class FilterAggregation extends Aggregation
8+
{
9+
private $aggregation;
10+
private $filter;
11+
12+
public function setFilter(Filter $filter)
13+
{
14+
$this->filter = $filter;
15+
16+
return $this;
17+
}
18+
19+
public function setAggregation(Aggregation $aggregation)
20+
{
21+
$this->aggregation = $aggregation;
22+
23+
return $this;
24+
}
25+
26+
public function build(): array
27+
{
28+
return [
29+
'filter' => $this->filter->build(),
30+
'aggs' => [
31+
$this->aggregation->getName() => $this->aggregation->build(),
32+
],
33+
];
34+
}
35+
}

Diff for: src/Aggregation/NestedAggregation.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Aggregation;
4+
5+
class NestedAggregation extends Aggregation
6+
{
7+
private $aggregation;
8+
private $path;
9+
10+
public function setNestedPath(string $path)
11+
{
12+
$this->path = $path;
13+
14+
return $this;
15+
}
16+
17+
public function setAggregation(Aggregation $aggregation)
18+
{
19+
$this->aggregation = $aggregation;
20+
21+
return $this;
22+
}
23+
24+
public function build(): array
25+
{
26+
return [
27+
'nested' => [
28+
'path' => $this->path,
29+
],
30+
'aggs' => [
31+
$this->aggregation->getName() => $this->aggregation->build(),
32+
],
33+
];
34+
}
35+
}

Diff for: src/Aggregation/TermsAggregation.php

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Aggregation;
4+
5+
class TermsAggregation extends Aggregation
6+
{
7+
private $field;
8+
private $script;
9+
private $size = 10;
10+
11+
public function setField(string $field)
12+
{
13+
$this->field = $field;
14+
15+
return $this;
16+
}
17+
18+
public function setSize(int $size)
19+
{
20+
$this->size = $size;
21+
22+
return $this;
23+
}
24+
25+
public function setScript(string $script)
26+
{
27+
$this->script = $script;
28+
29+
return $this;
30+
}
31+
32+
public function build(): array
33+
{
34+
if (null !== $this->script) {
35+
$term = [
36+
'script' => [
37+
'inline' => $this->script,
38+
'lang' => 'painless',
39+
],
40+
];
41+
} else {
42+
$term = [
43+
'field' => $this->field,
44+
'size' => $this->size,
45+
];
46+
}
47+
48+
return [
49+
'terms' => $term,
50+
];
51+
}
52+
}

Diff for: src/Filter/BoolFilter.php

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Filter;
4+
5+
use Erichard\ElasticQueryBuilder\QueryException;
6+
7+
class BoolFilter extends Filter
8+
{
9+
private $must = [];
10+
private $mustNot = [];
11+
private $should = [];
12+
private $filter = [];
13+
14+
public function addMust(Filter $filter)
15+
{
16+
$this->must[] = $filter;
17+
18+
return $this;
19+
}
20+
21+
public function addMustNot(Filter $filter)
22+
{
23+
$this->mustNot[] = $filter;
24+
25+
return $this;
26+
}
27+
28+
public function addShould(Filter $filter)
29+
{
30+
$this->should[] = $filter;
31+
32+
return $this;
33+
}
34+
35+
public function addFilter(Filter $filter)
36+
{
37+
$this->filter[] = $filter;
38+
39+
return $this;
40+
}
41+
42+
public function isEmpty()
43+
{
44+
return empty($this->must)
45+
&& empty($this->mustNot)
46+
&& empty($this->should)
47+
&& empty($this->filter)
48+
;
49+
}
50+
51+
public function build(): array
52+
{
53+
$filter = [];
54+
55+
if (!empty($this->must)) {
56+
$filter['must'] = [];
57+
foreach ($this->must as $f) {
58+
$filter['must'][] = $f->build();
59+
}
60+
}
61+
62+
if (!empty($this->mustNot)) {
63+
$filter['must_not'] = [];
64+
foreach ($this->mustNot as $f) {
65+
$filter['must_not'][] = $f->build();
66+
}
67+
}
68+
69+
if (!empty($this->filter)) {
70+
$filter['filter'] = [];
71+
foreach ($this->filter as $f) {
72+
$filter['filter'][] = $f->build();
73+
}
74+
}
75+
76+
if (!empty($this->should)) {
77+
$filter['should'] = [];
78+
foreach ($this->should as $f) {
79+
$filter['should'][] = $f->build();
80+
}
81+
}
82+
83+
if (empty($filter)) {
84+
throw new QueryException('Empty filter');
85+
}
86+
87+
return [
88+
'bool' => $filter,
89+
];
90+
}
91+
}

Diff for: src/Filter/Filter.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Filter;
4+
5+
abstract class Filter
6+
{
7+
abstract public function build(): array;
8+
9+
public static function terms()
10+
{
11+
return new TermsFilter();
12+
}
13+
14+
public static function term()
15+
{
16+
return new TermFilter();
17+
}
18+
19+
public static function bool()
20+
{
21+
return new BoolFilter();
22+
}
23+
24+
public static function range()
25+
{
26+
return new RangeFilter();
27+
}
28+
29+
public static function nested()
30+
{
31+
return new NestedFilter();
32+
}
33+
34+
public static function match()
35+
{
36+
return new MatchFilter();
37+
}
38+
39+
public static function geoDistance()
40+
{
41+
return new GeoDistanceFilter();
42+
}
43+
}

Diff for: src/Filter/GeoDistanceFilter.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Erichard\ElasticQueryBuilder\Filter;
4+
5+
class GeoDistanceFilter extends Filter
6+
{
7+
protected $distance;
8+
protected $pinLocation;
9+
10+
public function setDistance($distance)
11+
{
12+
$this->distance = $distance;
13+
14+
return $this;
15+
}
16+
17+
public function setPinLocation($pinLocation)
18+
{
19+
$this->pinLocation = $pinLocation;
20+
21+
return $this;
22+
}
23+
24+
public function build(): array
25+
{
26+
return [
27+
'geo_distance' => [
28+
'distance' => $this->distance,
29+
'geolocation' => $this->pinLocation,
30+
],
31+
];
32+
}
33+
}

0 commit comments

Comments
 (0)