These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Elastica\Test\Query; |
||
4 | |||
5 | use Elastica\Mapping; |
||
6 | use Elastica\Query\AbstractQuery; |
||
7 | use Elastica\Query\HasChild; |
||
8 | use Elastica\Query\InnerHits; |
||
9 | use Elastica\Query\MatchAll; |
||
10 | use Elastica\Query\Nested; |
||
11 | use Elastica\Query\SimpleQueryString; |
||
12 | use Elastica\Script\Script; |
||
13 | use Elastica\Script\ScriptFields; |
||
14 | use Elastica\Test\Base as BaseTest; |
||
15 | |||
16 | /** |
||
17 | * @internal |
||
18 | */ |
||
19 | class InnerHitsTest extends BaseTest |
||
20 | { |
||
21 | /** |
||
22 | * @group unit |
||
23 | */ |
||
24 | View Code Duplication | public function testSetSize(): void |
|
0 ignored issues
–
show
|
|||
25 | { |
||
26 | $innerHits = new InnerHits(); |
||
27 | $returnValue = $innerHits->setSize(12); |
||
28 | $this->assertEquals(12, $innerHits->getParam('size')); |
||
29 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
30 | } |
||
31 | |||
32 | /** |
||
33 | * @group unit |
||
34 | */ |
||
35 | View Code Duplication | public function testSetFrom(): void |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
36 | { |
||
37 | $innerHits = new InnerHits(); |
||
38 | $returnValue = $innerHits->setFrom(12); |
||
39 | $this->assertEquals(12, $innerHits->getParam('from')); |
||
40 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
41 | } |
||
42 | |||
43 | /** |
||
44 | * @group unit |
||
45 | */ |
||
46 | public function testSetSort(): void |
||
47 | { |
||
48 | $sort = ['last_activity_date' => ['order' => 'desc']]; |
||
49 | $innerHits = new InnerHits(); |
||
50 | $returnValue = $innerHits->setSort($sort); |
||
51 | $this->assertEquals($sort, $innerHits->getParam('sort')); |
||
52 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * @group unit |
||
57 | */ |
||
58 | public function testSetSource(): void |
||
59 | { |
||
60 | $fields = ['title', 'tags']; |
||
61 | $innerHits = new InnerHits(); |
||
62 | $returnValue = $innerHits->setSource($fields); |
||
63 | $this->assertEquals($fields, $innerHits->getParam('_source')); |
||
64 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
65 | } |
||
66 | |||
67 | /** |
||
68 | * @group unit |
||
69 | */ |
||
70 | public function testSetVersion(): void |
||
71 | { |
||
72 | $innerHits = new InnerHits(); |
||
73 | $returnValue = $innerHits->setVersion(true); |
||
74 | $this->assertTrue($innerHits->getParam('version')); |
||
75 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
76 | |||
77 | $innerHits->setVersion(false); |
||
78 | $this->assertFalse($innerHits->getParam('version')); |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * @group unit |
||
83 | */ |
||
84 | public function testSetExplain(): void |
||
85 | { |
||
86 | $innerHits = new InnerHits(); |
||
87 | $returnValue = $innerHits->setExplain(true); |
||
88 | $this->assertTrue($innerHits->getParam('explain')); |
||
89 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
90 | |||
91 | $innerHits->setExplain(false); |
||
92 | $this->assertFalse($innerHits->getParam('explain')); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * @group unit |
||
97 | */ |
||
98 | public function testSetHighlight(): void |
||
99 | { |
||
100 | $highlight = [ |
||
101 | 'fields' => [ |
||
102 | 'title', |
||
103 | ], |
||
104 | ]; |
||
105 | $innerHits = new InnerHits(); |
||
106 | $returnValue = $innerHits->setHighlight($highlight); |
||
107 | $this->assertEquals($highlight, $innerHits->getParam('highlight')); |
||
108 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * @group unit |
||
113 | */ |
||
114 | public function testSetFieldDataFields(): void |
||
115 | { |
||
116 | $fields = ['title', 'tags']; |
||
117 | $innerHits = new InnerHits(); |
||
118 | $returnValue = $innerHits->setFieldDataFields($fields); |
||
119 | $this->assertEquals($fields, $innerHits->getParam('docvalue_fields')); |
||
120 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * @group unit |
||
125 | */ |
||
126 | public function testSetScriptFields(): void |
||
127 | { |
||
128 | $script = new Script('1 + 2'); |
||
129 | $scriptFields = new ScriptFields(['three' => $script]); |
||
130 | |||
131 | $innerHits = new InnerHits(); |
||
132 | $returnValue = $innerHits->setScriptFields($scriptFields); |
||
133 | $this->assertEquals($scriptFields->toArray(), $innerHits->getParam('script_fields')->toArray()); |
||
134 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * @group unit |
||
139 | */ |
||
140 | View Code Duplication | public function testAddScriptField(): void |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
141 | { |
||
142 | $script = new Script('2+3'); |
||
143 | $innerHits = new InnerHits(); |
||
144 | $returnValue = $innerHits->addScriptField('five', $script); |
||
145 | $this->assertEquals(['five' => $script->toArray()], $innerHits->getParam('script_fields')->toArray()); |
||
146 | $this->assertInstanceOf(InnerHits::class, $returnValue); |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @group functional |
||
151 | */ |
||
152 | public function testInnerHitsNested(): void |
||
153 | { |
||
154 | $queryString = new SimpleQueryString('windows newton', ['title', 'users.name']); |
||
155 | $innerHits = new InnerHits(); |
||
156 | |||
157 | $results = $this->getNestedQuery($queryString, $innerHits); |
||
158 | $firstResult = \current($results->getResults()); |
||
159 | |||
160 | $innerHitsResults = $firstResult->getInnerHits(); |
||
161 | |||
162 | $this->assertEquals($firstResult->getId(), 4); |
||
163 | $this->assertEquals($innerHitsResults['users']['hits']['hits'][0]['_source']['name'], 'Newton'); |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * @group functional |
||
168 | */ |
||
169 | View Code Duplication | public function testInnerHitsParentChildren(): void |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
170 | { |
||
171 | $queryString = new SimpleQueryString('linux cool'); |
||
172 | $innerHits = new InnerHits(); |
||
173 | |||
174 | $results = $this->getParentChildQuery($queryString, $innerHits); |
||
175 | $firstResult = \current($results->getResults()); |
||
176 | |||
177 | $innerHits = $firstResult->getInnerHits(); |
||
178 | |||
179 | $responses = $innerHits['answers']['hits']['hits']; |
||
180 | $responsesId = []; |
||
181 | |||
182 | foreach ($responses as $response) { |
||
183 | $responsesId[] = $response['_id']; |
||
184 | } |
||
185 | |||
186 | $this->assertEquals($firstResult->getId(), 1); |
||
187 | $this->assertEquals([6, 7], $responsesId); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * @group functional |
||
192 | */ |
||
193 | public function testInnerHitsLimitedSource(): void |
||
194 | { |
||
195 | $this->markTestSkipped('Source filtering on inner hits is bugged. See https://github.com/elastic/elasticsearch/issues/21312'); |
||
196 | |||
197 | $innerHits = new InnerHits(); |
||
198 | $innerHits->setSource(['includes' => ['name'], 'excludes' => ['last_activity_date']]); |
||
199 | |||
200 | $results = $this->getNestedQuery(new MatchAll(), $innerHits); |
||
201 | |||
202 | foreach ($results as $row) { |
||
203 | $innerHitsResult = $row->getInnerHits(); |
||
204 | foreach ($innerHitsResult['users']['hits']['hits'] as $doc) { |
||
205 | $this->assertArrayHasKey('name', $doc['_source']['users']); |
||
206 | $this->assertArrayNotHasKey('last_activity_date', $doc['_source']['users']); |
||
207 | } |
||
208 | } |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * @group functional |
||
213 | */ |
||
214 | public function testInnerHitsWithOffset(): void |
||
215 | { |
||
216 | $queryString = new SimpleQueryString('linux cool'); |
||
217 | $innerHits = new InnerHits(); |
||
218 | $innerHits->setFrom(1); |
||
219 | |||
220 | $results = $this->getParentChildQuery($queryString, $innerHits); |
||
221 | $firstResult = \current($results->getResults()); |
||
222 | |||
223 | $innerHits = $firstResult->getInnerHits(); |
||
224 | |||
225 | $responses = $innerHits['answers']['hits']['hits']; |
||
226 | |||
227 | $this->assertEquals(\count($responses), 1); |
||
228 | $this->assertEquals(7, $responses[0]['_id']); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * @group functional |
||
233 | */ |
||
234 | View Code Duplication | public function testInnerHitsWithSort(): void |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
235 | { |
||
236 | $queryString = new SimpleQueryString('linux cool'); |
||
237 | $innerHits = new InnerHits(); |
||
238 | $innerHits->setSort(['answer' => 'asc']); |
||
239 | |||
240 | $results = $this->getParentChildQuery($queryString, $innerHits); |
||
241 | $firstResult = \current($results->getResults()); |
||
242 | |||
243 | $innerHits = $firstResult->getInnerHits(); |
||
244 | |||
245 | $responses = $innerHits['answers']['hits']['hits']; |
||
246 | $responsesId = []; |
||
247 | |||
248 | foreach ($responses as $response) { |
||
249 | $responsesId[] = $response['_id']; |
||
250 | } |
||
251 | |||
252 | $this->assertEquals($firstResult->getId(), 1); |
||
253 | $this->assertEquals([7, 6], $responsesId); |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * @group functional |
||
258 | */ |
||
259 | View Code Duplication | public function testInnerHitsWithExplain(): void |
|
260 | { |
||
261 | $matchAll = new MatchAll(); |
||
262 | $innerHits = new InnerHits(); |
||
263 | $innerHits->setExplain(true); |
||
264 | |||
265 | $results = $this->getNestedQuery($matchAll, $innerHits); |
||
266 | |||
267 | foreach ($results as $row) { |
||
268 | $innerHitsResult = $row->getInnerHits(); |
||
269 | foreach ($innerHitsResult['users']['hits']['hits'] as $doc) { |
||
270 | $this->assertArrayHasKey('_explanation', $doc); |
||
271 | } |
||
272 | } |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * @group functional |
||
277 | */ |
||
278 | View Code Duplication | public function testInnerHitsWithVersion(): void |
|
279 | { |
||
280 | $matchAll = new MatchAll(); |
||
281 | $innerHits = new InnerHits(); |
||
282 | $innerHits->setVersion(true); |
||
283 | |||
284 | $results = $this->getNestedQuery($matchAll, $innerHits); |
||
285 | |||
286 | foreach ($results as $row) { |
||
287 | $innerHitsResult = $row->getInnerHits(); |
||
288 | foreach ($innerHitsResult['users']['hits']['hits'] as $doc) { |
||
289 | $this->assertArrayHasKey('_version', $doc); |
||
290 | } |
||
291 | } |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * @group functional |
||
296 | */ |
||
297 | public function testInnerHitsWithScriptFields(): void |
||
298 | { |
||
299 | $matchAll = new MatchAll(); |
||
300 | $innerHits = new InnerHits(); |
||
301 | $innerHits->setSize(1); |
||
302 | $scriptFields = new ScriptFields(); |
||
303 | $scriptFields->addScript('three', new Script('1 + 2')); |
||
304 | $scriptFields->addScript('five', new Script('3 + 2')); |
||
305 | $innerHits->setScriptFields($scriptFields); |
||
306 | |||
307 | $results = $this->getNestedQuery($matchAll, $innerHits); |
||
308 | |||
309 | View Code Duplication | foreach ($results as $row) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
310 | $innerHitsResult = $row->getInnerHits(); |
||
311 | foreach ($innerHitsResult['users']['hits']['hits'] as $doc) { |
||
312 | $this->assertEquals(3, $doc['fields']['three'][0]); |
||
313 | $this->assertEquals(5, $doc['fields']['five'][0]); |
||
314 | } |
||
315 | } |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * @group functional |
||
320 | */ |
||
321 | View Code Duplication | public function testInnerHitsWithHighlight(): void |
|
322 | { |
||
323 | $queryString = new SimpleQueryString('question simon', ['title', 'users.name']); |
||
324 | $innerHits = new InnerHits(); |
||
325 | $innerHits->setHighlight(['fields' => ['users.name' => new \stdClass()]]); |
||
326 | |||
327 | $results = $this->getNestedQuery($queryString, $innerHits); |
||
328 | |||
329 | foreach ($results as $row) { |
||
330 | $innerHitsResult = $row->getInnerHits(); |
||
331 | foreach ($innerHitsResult['users']['hits']['hits'] as $doc) { |
||
332 | $this->assertArrayHasKey('highlight', $doc); |
||
333 | $this->assertRegExp('#<em>Simon</em>#', $doc['highlight']['users.name'][0]); |
||
334 | } |
||
335 | } |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * @group functional |
||
340 | */ |
||
341 | View Code Duplication | public function testInnerHitsWithFieldData(): void |
|
342 | { |
||
343 | $queryString = new SimpleQueryString('question simon', ['title', 'users.name']); |
||
344 | $innerHits = new InnerHits(); |
||
345 | |||
346 | $innerHits->setFieldDataFields(['users.name']); |
||
347 | |||
348 | $results = $this->getNestedQuery($queryString, $innerHits); |
||
349 | |||
350 | foreach ($results as $row) { |
||
351 | $innerHitsResult = $row->getInnerHits(); |
||
352 | foreach ($innerHitsResult['users']['hits']['hits'] as $doc) { |
||
353 | $this->assertArrayHasKey('fields', $doc); |
||
354 | $this->assertArrayHasKey('users.name', $doc['fields']); |
||
355 | $this->assertArrayNotHasKey('users.last_activity_date', $doc['fields']); |
||
356 | } |
||
357 | } |
||
358 | } |
||
359 | |||
360 | private function _getIndexForNestedTest() |
||
361 | { |
||
362 | $index = $this->_createIndex(); |
||
363 | $index->setMapping(new Mapping([ |
||
364 | 'users' => [ |
||
365 | 'type' => 'nested', |
||
366 | 'properties' => [ |
||
367 | 'name' => ['type' => 'text', 'fielddata' => true], |
||
368 | ], |
||
369 | ], |
||
370 | 'title' => ['type' => 'text'], |
||
371 | 'last_activity_date' => ['type' => 'date'], |
||
372 | ])); |
||
373 | |||
374 | $index->addDocuments([ |
||
375 | $index->createDocument(1, [ |
||
376 | 'users' => [ |
||
377 | ['name' => 'John Smith', 'last_activity_date' => '2015-01-05'], |
||
378 | ['name' => 'Conan', 'last_activity_date' => '2015-01-05'], |
||
379 | ], |
||
380 | 'last_activity_date' => '2015-01-05', |
||
381 | 'title' => 'Question about linux #1', |
||
382 | ]), |
||
383 | $index->createDocument(2, [ |
||
384 | 'users' => [ |
||
385 | ['name' => 'John Doe', 'last_activity_date' => '2015-01-05'], |
||
386 | ['name' => 'Simon', 'last_activity_date' => '2015-01-05'], |
||
387 | ], |
||
388 | 'last_activity_date' => '2014-12-23', |
||
389 | 'title' => 'Question about linux #2', |
||
390 | ]), |
||
391 | $index->createDocument(3, [ |
||
392 | 'users' => [ |
||
393 | ['name' => 'Simon', 'last_activity_date' => '2015-01-05'], |
||
394 | ['name' => 'Garfunkel', 'last_activity_date' => '2015-01-05'], |
||
395 | ], |
||
396 | 'last_activity_date' => '2015-01-05', |
||
397 | 'title' => 'Question about windows #1', |
||
398 | ]), |
||
399 | $index->createDocument(4, [ |
||
400 | 'users' => [ |
||
401 | ['name' => 'Einstein'], |
||
402 | ['name' => 'Newton'], |
||
403 | ['name' => 'Maxwell'], |
||
404 | ], |
||
405 | 'last_activity_date' => '2014-12-23', |
||
406 | 'title' => 'Question about windows #2', |
||
407 | ]), |
||
408 | $index->createDocument(5, [ |
||
409 | 'users' => [ |
||
410 | ['name' => 'Faraday'], |
||
411 | ['name' => 'Leibniz'], |
||
412 | ['name' => 'Descartes'], |
||
413 | ], |
||
414 | 'last_activity_date' => '2014-12-23', |
||
415 | 'title' => 'Question about osx', |
||
416 | ]), |
||
417 | ]); |
||
418 | |||
419 | $index->refresh(); |
||
420 | |||
421 | return $index; |
||
422 | } |
||
423 | |||
424 | private function _getIndexForParentChildrenTest() |
||
425 | { |
||
426 | $index = $this->_createIndex(); |
||
427 | $mappingQuestion = new Mapping(); |
||
428 | $mappingQuestion->setProperties([ |
||
429 | 'title' => ['type' => 'text'], |
||
430 | 'answer' => ['type' => 'text', 'fielddata' => true], |
||
431 | 'last_activity_date' => ['type' => 'date'], |
||
432 | 'my_join_field' => [ |
||
433 | 'type' => 'join', |
||
434 | 'relations' => [ |
||
435 | 'questions' => 'answers', |
||
436 | ], |
||
437 | ], |
||
438 | ]); |
||
439 | |||
440 | $index->setMapping($mappingQuestion); |
||
441 | $index->addDocuments([ |
||
442 | $index->createDocument(1, [ |
||
443 | 'last_activity_date' => '2015-01-05', |
||
444 | 'title' => 'Question about linux #1', |
||
445 | 'my_join_field' => [ |
||
446 | 'name' => 'questions', |
||
447 | ], |
||
448 | ]), |
||
449 | $index->createDocument(2, [ |
||
450 | 'last_activity_date' => '2014-12-23', |
||
451 | 'title' => 'Question about linux #2', |
||
452 | 'my_join_field' => [ |
||
453 | 'name' => 'questions', |
||
454 | ], |
||
455 | ]), |
||
456 | $index->createDocument(3, [ |
||
457 | 'last_activity_date' => '2015-01-05', |
||
458 | 'title' => 'Question about windows #1', |
||
459 | 'my_join_field' => [ |
||
460 | 'name' => 'questions', |
||
461 | ], |
||
462 | ]), |
||
463 | $index->createDocument(4, [ |
||
464 | 'last_activity_date' => '2014-12-23', |
||
465 | 'title' => 'Question about windows #2', |
||
466 | 'my_join_field' => [ |
||
467 | 'name' => 'questions', |
||
468 | ], |
||
469 | ]), |
||
470 | $index->createDocument(5, [ |
||
471 | 'last_activity_date' => '2014-12-23', |
||
472 | 'title' => 'Question about osx', |
||
473 | 'my_join_field' => [ |
||
474 | 'name' => 'questions', |
||
475 | ], |
||
476 | ]), |
||
477 | ]); |
||
478 | |||
479 | $doc1 = $index->createDocument(6, [ |
||
480 | 'answer' => 'linux is cool', |
||
481 | 'last_activity_date' => '2016-01-05', |
||
482 | 'my_join_field' => [ |
||
483 | 'name' => 'answers', |
||
484 | 'parent' => 1, |
||
485 | ], |
||
486 | ]); |
||
487 | |||
488 | $doc2 = $index->createDocument(7, [ |
||
489 | 'answer' => 'linux is bad', |
||
490 | 'last_activity_date' => '2005-01-05', |
||
491 | 'my_join_field' => [ |
||
492 | 'name' => 'answers', |
||
493 | 'parent' => 1, |
||
494 | ], |
||
495 | ]); |
||
496 | |||
497 | $doc3 = $index->createDocument(8, [ |
||
498 | 'answer' => 'windows was cool', |
||
499 | 'last_activity_date' => '2005-01-05', |
||
500 | 'my_join_field' => [ |
||
501 | 'name' => 'answers', |
||
502 | 'parent' => 2, |
||
503 | ], |
||
504 | ]); |
||
505 | |||
506 | $this->_getClient()->addDocuments([$doc1, $doc2, $doc3], ['routing' => 1]); |
||
507 | |||
508 | $index->refresh(); |
||
509 | |||
510 | return $index; |
||
511 | } |
||
512 | |||
513 | private function getNestedQuery(AbstractQuery $query, InnerHits $innerHits) |
||
514 | { |
||
515 | $nested = (new Nested()) |
||
516 | ->setInnerHits($innerHits) |
||
517 | ->setPath('users') |
||
518 | ->setQuery($query) |
||
519 | ; |
||
520 | |||
521 | return $this->_getIndexForNestedTest()->search($nested); |
||
522 | } |
||
523 | |||
524 | private function getParentChildQuery(AbstractQuery $query, InnerHits $innerHits) |
||
525 | { |
||
526 | $child = (new HasChild($query, 'answers'))->setInnerHits($innerHits); |
||
527 | |||
528 | return $this->_getIndexForParentChildrenTest()->search($child); |
||
529 | } |
||
530 | } |
||
531 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.