-
-
Notifications
You must be signed in to change notification settings - Fork 842
/
TermFilter.php
124 lines (118 loc) · 3.97 KB
/
TermFilter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace ApiPlatform\Elasticsearch\Filter;
/**
* The term filter allows to find resources that contain the exact specified [terms](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html).
*
* Syntax: `?property[]=value`.
*
* <div data-code-selector>
*
* ```php
* <?php
* // api/src/Entity/Book.php
* use ApiPlatform\Metadata\ApiFilter;
* use ApiPlatform\Metadata\ApiResource;
* use ApiPlatform\Elasticsearch\Filter\TermFilter;
*
* #[ApiResource]
* #[ApiFilter(TermFilter::class, properties: ['title'])]
* class Book
* {
* // ...
* }
* ```
*
* ```yaml
* # config/services.yaml
* services:
* book.term_filter:
* parent: 'api_platform.elasticsearch.term_filter'
* arguments: [ { title: ~ } ]
* tags: [ 'api_platform.filter' ]
* # The following are mandatory only if a _defaults section is defined with inverted values.
* # You may want to isolate filters in a dedicated file to avoid adding the following lines (by adding them in the defaults section)
* autowire: false
* autoconfigure: false
* public: false
*
* # api/config/api_platform/resources.yaml
* resources:
* App\Entity\Book:
* - operations:
* ApiPlatform\Metadata\GetCollection:
* filters: ['book.term_filter']
* ```
* ```xml
* <?xml version="1.0" encoding="UTF-8" ?>
* <!-- api/config/services.xml -->
* <?xml version="1.0" encoding="UTF-8" ?>
* <container
* xmlns="http://symfony.com/schema/dic/services"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xsi:schemaLocation="http://symfony.com/schema/dic/services
* https://symfony.com/schema/dic/services/services-1.0.xsd">
* <services>
* <service id="book.term_filter" parent="api_platform.elasticsearch.term_filter">
* <argument type="collection">
* <argument key="title"/>
* </argument>
* <tag name="api_platform.filter"/>
* </service>
* </services>
* </container>
* <!-- api/config/api_platform/resources.xml -->
* <resources
* xmlns="https://api-platform.com/schema/metadata/resources-3.0"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
* https://api-platform.com/schema/metadata/resources-3.0.xsd">
* <resource class="App\Entity\Book">
* <operations>
* <operation class="ApiPlatform\Metadata\GetCollection">
* <filters>
* <filter>book.term_filter</filter>
* </filters>
* </operation>
* </operations>
* </resource>
* </resources>
* ```
*
* </div>
*
* Given that the collection endpoint is `/books`, you can filter books by title with the following query: `/books?title=Foundation`.
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
*
* @experimental
*
* @author Baptiste Meyer <baptiste.meyer@gmail.com>
*/
final class TermFilter extends AbstractSearchFilter
{
/**
* {@inheritdoc}
*/
protected function getQuery(string $property, array $values, ?string $nestedPath): array
{
if (1 === \count($values)) {
$termQuery = ['term' => [$property => reset($values)]];
} else {
$termQuery = ['terms' => [$property => $values]];
}
if (null !== $nestedPath) {
$termQuery = ['nested' => ['path' => $nestedPath, 'query' => $termQuery]];
}
return $termQuery;
}
}