Completed
Push — master ( 0d45ed...ea3502 )
by Nicolas
02:38
created

tests/Query/InnerHitsTest.php (6 issues)

Upgrade to new PHP Analysis Engine

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
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.

Loading history...
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.

Loading history...
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.

Loading history...
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.

Loading history...
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.

Loading history...
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.

Loading history...
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