|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Elastica\Test\Aggregation; |
|
4
|
|
|
|
|
5
|
|
|
use Elastica\Aggregation\Terms; |
|
6
|
|
|
use Elastica\Aggregation\TopHits; |
|
7
|
|
|
use Elastica\Document; |
|
8
|
|
|
use Elastica\Index; |
|
9
|
|
|
use Elastica\Mapping; |
|
10
|
|
|
use Elastica\Query; |
|
11
|
|
|
use Elastica\Query\MatchAll; |
|
12
|
|
|
use Elastica\Query\SimpleQueryString; |
|
13
|
|
|
use Elastica\Script\Script; |
|
14
|
|
|
use Elastica\Script\ScriptFields; |
|
15
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* @internal |
|
18
|
|
|
*/ |
|
19
|
|
|
class TopHitsTest extends BaseAggregationTest |
|
20
|
|
|
{ |
|
21
|
|
|
/** |
|
22
|
|
|
* @group unit |
|
23
|
|
|
*/ |
|
24
|
|
|
public function testSetSize(): void |
|
25
|
|
|
{ |
|
26
|
|
|
$agg = new TopHits('agg_name'); |
|
27
|
|
|
$returnValue = $agg->setSize(12); |
|
28
|
|
|
$this->assertEquals(12, $agg->getParam('size')); |
|
29
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
30
|
|
|
} |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* @group unit |
|
34
|
|
|
*/ |
|
35
|
|
View Code Duplication |
public function testSetFrom(): void |
|
|
|
|
|
|
36
|
|
|
{ |
|
37
|
|
|
$agg = new TopHits('agg_name'); |
|
38
|
|
|
$returnValue = $agg->setFrom(12); |
|
39
|
|
|
$this->assertEquals(12, $agg->getParam('from')); |
|
40
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
41
|
|
|
} |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @group unit |
|
45
|
|
|
*/ |
|
46
|
|
|
public function testSetSort(): void |
|
47
|
|
|
{ |
|
48
|
|
|
$sort = ['last_activity_date' => ['order' => 'desc']]; |
|
49
|
|
|
$agg = new TopHits('agg_name'); |
|
50
|
|
|
$returnValue = $agg->setSort($sort); |
|
51
|
|
|
$this->assertEquals($sort, $agg->getParam('sort')); |
|
52
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* @group unit |
|
57
|
|
|
*/ |
|
58
|
|
View Code Duplication |
public function testSetSource(): void |
|
|
|
|
|
|
59
|
|
|
{ |
|
60
|
|
|
$fields = ['title', 'tags']; |
|
61
|
|
|
$agg = new TopHits('agg_name'); |
|
62
|
|
|
$returnValue = $agg->setSource($fields); |
|
63
|
|
|
$this->assertEquals($fields, $agg->getParam('_source')); |
|
64
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
/** |
|
68
|
|
|
* @group unit |
|
69
|
|
|
*/ |
|
70
|
|
View Code Duplication |
public function testSetVersion(): void |
|
|
|
|
|
|
71
|
|
|
{ |
|
72
|
|
|
$agg = new TopHits('agg_name'); |
|
73
|
|
|
$returnValue = $agg->setVersion(true); |
|
74
|
|
|
$this->assertTrue($agg->getParam('version')); |
|
75
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
76
|
|
|
|
|
77
|
|
|
$agg->setVersion(false); |
|
78
|
|
|
$this->assertFalse($agg->getParam('version')); |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
/** |
|
82
|
|
|
* @group unit |
|
83
|
|
|
*/ |
|
84
|
|
View Code Duplication |
public function testSetExplain(): void |
|
|
|
|
|
|
85
|
|
|
{ |
|
86
|
|
|
$agg = new TopHits('agg_name'); |
|
87
|
|
|
$returnValue = $agg->setExplain(true); |
|
88
|
|
|
$this->assertTrue($agg->getParam('explain')); |
|
89
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
90
|
|
|
|
|
91
|
|
|
$agg->setExplain(false); |
|
92
|
|
|
$this->assertFalse($agg->getParam('explain')); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* @group unit |
|
97
|
|
|
*/ |
|
98
|
|
|
public function testSetHighlight(): void |
|
99
|
|
|
{ |
|
100
|
|
|
$highlight = [ |
|
101
|
|
|
'fields' => [ |
|
102
|
|
|
'title', |
|
103
|
|
|
], |
|
104
|
|
|
]; |
|
105
|
|
|
$agg = new TopHits('agg_name'); |
|
106
|
|
|
$returnValue = $agg->setHighlight($highlight); |
|
107
|
|
|
$this->assertEquals($highlight, $agg->getParam('highlight')); |
|
108
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* @group unit |
|
113
|
|
|
*/ |
|
114
|
|
View Code Duplication |
public function testSetFieldDataFields(): void |
|
|
|
|
|
|
115
|
|
|
{ |
|
116
|
|
|
$fields = ['title', 'tags']; |
|
117
|
|
|
$agg = new TopHits('agg_name'); |
|
118
|
|
|
$returnValue = $agg->setFieldDataFields($fields); |
|
119
|
|
|
$this->assertEquals($fields, $agg->getParam('docvalue_fields')); |
|
120
|
|
|
$this->assertInstanceOf(TopHits::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
|
|
|
$agg = new TopHits('agg_name'); |
|
132
|
|
|
$returnValue = $agg->setScriptFields($scriptFields); |
|
133
|
|
|
$this->assertEquals($scriptFields->toArray(), $agg->getParam('script_fields')->toArray()); |
|
134
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
/** |
|
138
|
|
|
* @group unit |
|
139
|
|
|
*/ |
|
140
|
|
|
public function testAddScriptField(): void |
|
141
|
|
|
{ |
|
142
|
|
|
$script = new Script('2+3'); |
|
143
|
|
|
$agg = new TopHits('agg_name'); |
|
144
|
|
|
$returnValue = $agg->addScriptField('five', $script); |
|
145
|
|
|
$this->assertEquals(['five' => $script->toArray()], $agg->getParam('script_fields')->toArray()); |
|
146
|
|
|
$this->assertInstanceOf(TopHits::class, $returnValue); |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
/** |
|
150
|
|
|
* @group functional |
|
151
|
|
|
*/ |
|
152
|
|
View Code Duplication |
public function testAggregateUpdatedRecently(): void |
|
|
|
|
|
|
153
|
|
|
{ |
|
154
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
155
|
|
|
$aggr->setSize(1); |
|
156
|
|
|
$aggr->setSort(['last_activity_date' => ['order' => 'desc']]); |
|
157
|
|
|
|
|
158
|
|
|
$resultDocs = []; |
|
159
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
160
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
161
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
162
|
|
|
$resultDocs[] = $doc['_id']; |
|
163
|
|
|
} |
|
164
|
|
|
} |
|
165
|
|
|
$this->assertEquals([1, 3], $resultDocs); |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* @group functional |
|
170
|
|
|
*/ |
|
171
|
|
View Code Duplication |
public function testAggregateUpdatedFarAgo(): void |
|
|
|
|
|
|
172
|
|
|
{ |
|
173
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
174
|
|
|
$aggr->setSize(1); |
|
175
|
|
|
$aggr->setSort(['last_activity_date' => ['order' => 'asc']]); |
|
176
|
|
|
|
|
177
|
|
|
$resultDocs = []; |
|
178
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
179
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
180
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
181
|
|
|
$resultDocs[] = $doc['_id']; |
|
182
|
|
|
} |
|
183
|
|
|
} |
|
184
|
|
|
$this->assertEquals([2, 4], $resultDocs); |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
/** |
|
188
|
|
|
* @group functional |
|
189
|
|
|
*/ |
|
190
|
|
View Code Duplication |
public function testAggregateTwoDocumentPerTag(): void |
|
|
|
|
|
|
191
|
|
|
{ |
|
192
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
193
|
|
|
$aggr->setSize(2); |
|
194
|
|
|
|
|
195
|
|
|
$resultDocs = []; |
|
196
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
197
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
198
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
199
|
|
|
$resultDocs[] = $doc['_id']; |
|
200
|
|
|
} |
|
201
|
|
|
} |
|
202
|
|
|
$this->assertEquals([1, 2, 3, 4], $resultDocs); |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
|
|
/** |
|
206
|
|
|
* @group functional |
|
207
|
|
|
*/ |
|
208
|
|
View Code Duplication |
public function testAggregateTwoDocumentPerTagWithOffset(): void |
|
|
|
|
|
|
209
|
|
|
{ |
|
210
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
211
|
|
|
$aggr->setSize(2); |
|
212
|
|
|
$aggr->setFrom(1); |
|
213
|
|
|
$aggr->setSort(['last_activity_date' => ['order' => 'desc']]); |
|
214
|
|
|
|
|
215
|
|
|
$resultDocs = []; |
|
216
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
217
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
218
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
219
|
|
|
$resultDocs[] = $doc['_id']; |
|
220
|
|
|
} |
|
221
|
|
|
} |
|
222
|
|
|
$this->assertEquals([2, 4], $resultDocs); |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
public function limitedSourceProvider() |
|
226
|
|
|
{ |
|
227
|
|
|
return [ |
|
228
|
|
|
'string source' => ['title'], |
|
229
|
|
|
'array source' => [['title']], |
|
230
|
|
|
]; |
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
/** |
|
234
|
|
|
* @group functional |
|
235
|
|
|
* @dataProvider limitedSourceProvider |
|
236
|
|
|
* |
|
237
|
|
|
* @param mixed $source |
|
238
|
|
|
*/ |
|
239
|
|
|
public function testAggregateWithLimitedSource($source): void |
|
240
|
|
|
{ |
|
241
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
242
|
|
|
$aggr->setSource($source); |
|
243
|
|
|
|
|
244
|
|
|
$resultDocs = []; |
|
|
|
|
|
|
245
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
246
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
247
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
248
|
|
|
$this->assertArrayHasKey('title', $doc['_source']); |
|
249
|
|
|
$this->assertArrayNotHasKey('tags', $doc['_source']); |
|
250
|
|
|
$this->assertArrayNotHasKey('last_activity_date', $doc['_source']); |
|
251
|
|
|
} |
|
252
|
|
|
} |
|
253
|
|
|
} |
|
254
|
|
|
|
|
255
|
|
|
/** |
|
256
|
|
|
* @group functional |
|
257
|
|
|
*/ |
|
258
|
|
View Code Duplication |
public function testAggregateWithVersion(): void |
|
|
|
|
|
|
259
|
|
|
{ |
|
260
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
261
|
|
|
$aggr->setVersion(true); |
|
262
|
|
|
|
|
263
|
|
|
$resultDocs = []; |
|
|
|
|
|
|
264
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
265
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
266
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
267
|
|
|
$this->assertArrayHasKey('_version', $doc); |
|
268
|
|
|
} |
|
269
|
|
|
} |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
/** |
|
273
|
|
|
* @group functional |
|
274
|
|
|
*/ |
|
275
|
|
View Code Duplication |
public function testAggregateWithExplain(): void |
|
|
|
|
|
|
276
|
|
|
{ |
|
277
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
278
|
|
|
$aggr->setExplain(true); |
|
279
|
|
|
|
|
280
|
|
|
$resultDocs = []; |
|
|
|
|
|
|
281
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
282
|
|
|
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
283
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
284
|
|
|
$this->assertArrayHasKey('_explanation', $doc); |
|
285
|
|
|
} |
|
286
|
|
|
} |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
/** |
|
290
|
|
|
* @group functional |
|
291
|
|
|
*/ |
|
292
|
|
|
public function testAggregateWithScriptFields(): void |
|
293
|
|
|
{ |
|
294
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
295
|
|
|
$aggr->setSize(1); |
|
296
|
|
|
$aggr->setScriptFields(['three' => new Script('1 + 2')]); |
|
297
|
|
|
$aggr->addScriptField('five', new Script('3 + 2')); |
|
298
|
|
|
|
|
299
|
|
|
$resultDocs = []; |
|
|
|
|
|
|
300
|
|
|
$outerAggrResult = $this->getOuterAggregationResult($aggr); |
|
301
|
|
View Code Duplication |
foreach ($outerAggrResult['buckets'] as $bucket) { |
|
|
|
|
|
|
302
|
|
|
foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) { |
|
303
|
|
|
$this->assertEquals(3, $doc['fields']['three'][0]); |
|
304
|
|
|
$this->assertEquals(5, $doc['fields']['five'][0]); |
|
305
|
|
|
} |
|
306
|
|
|
} |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
/** |
|
310
|
|
|
* @group functional |
|
311
|
|
|
*/ |
|
312
|
|
|
public function testAggregateWithHighlight(): void |
|
313
|
|
|
{ |
|
314
|
|
|
$queryString = new SimpleQueryString('linux', ['title']); |
|
315
|
|
|
|
|
316
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
317
|
|
|
$aggr->setHighlight(['fields' => ['title' => new \stdClass()]]); |
|
318
|
|
|
|
|
319
|
|
|
$query = new Query($queryString); |
|
320
|
|
|
$query->addAggregation($aggr); |
|
321
|
|
|
|
|
322
|
|
|
$resultSet = $this->_getIndexForTest()->search($query); |
|
323
|
|
|
$aggrResult = $resultSet->getAggregation('top_tag_hits'); |
|
324
|
|
|
|
|
325
|
|
|
foreach ($aggrResult['hits']['hits'] as $doc) { |
|
326
|
|
|
$this->assertArrayHasKey('highlight', $doc); |
|
327
|
|
|
$this->assertRegExp('#<em>linux</em>#', $doc['highlight']['title'][0]); |
|
328
|
|
|
} |
|
329
|
|
|
} |
|
330
|
|
|
|
|
331
|
|
|
/** |
|
332
|
|
|
* @group functional |
|
333
|
|
|
*/ |
|
334
|
|
|
public function testAggregateWithFieldData(): void |
|
335
|
|
|
{ |
|
336
|
|
|
$aggr = new TopHits('top_tag_hits'); |
|
337
|
|
|
$aggr->setFieldDataFields(['title']); |
|
338
|
|
|
|
|
339
|
|
|
$query = new Query(new MatchAll()); |
|
340
|
|
|
$query->addAggregation($aggr); |
|
341
|
|
|
|
|
342
|
|
|
$resultSet = $this->_getIndexForTest()->search($query); |
|
343
|
|
|
$aggrResult = $resultSet->getAggregation('top_tag_hits'); |
|
344
|
|
|
|
|
345
|
|
|
foreach ($aggrResult['hits']['hits'] as $doc) { |
|
346
|
|
|
$this->assertArrayHasKey('fields', $doc); |
|
347
|
|
|
$this->assertArrayHasKey('title', $doc['fields']); |
|
348
|
|
|
$this->assertArrayNotHasKey('tags', $doc['fields']); |
|
349
|
|
|
$this->assertArrayNotHasKey('last_activity_date', $doc['fields']); |
|
350
|
|
|
} |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
protected function _getIndexForTest(): Index |
|
354
|
|
|
{ |
|
355
|
|
|
$index = $this->_createIndex(); |
|
356
|
|
|
$mapping = new Mapping([ |
|
357
|
|
|
'tags' => ['type' => 'keyword'], |
|
358
|
|
|
'title' => ['type' => 'keyword'], |
|
359
|
|
|
'my_join_field' => [ |
|
360
|
|
|
'type' => 'join', |
|
361
|
|
|
'relations' => [ |
|
362
|
|
|
'question' => 'answer', |
|
363
|
|
|
], |
|
364
|
|
|
], |
|
365
|
|
|
]); |
|
366
|
|
|
$index->setMapping($mapping); |
|
367
|
|
|
|
|
368
|
|
|
$index->addDocuments([ |
|
369
|
|
|
new Document(1, [ |
|
370
|
|
|
'tags' => ['linux'], |
|
371
|
|
|
'last_activity_date' => '2015-01-05', |
|
372
|
|
|
'title' => 'Question about linux #1', |
|
373
|
|
|
]), |
|
374
|
|
|
new Document(2, [ |
|
375
|
|
|
'tags' => ['linux'], |
|
376
|
|
|
'last_activity_date' => '2014-12-23', |
|
377
|
|
|
'title' => 'Question about linux #2', |
|
378
|
|
|
]), |
|
379
|
|
|
new Document(3, [ |
|
380
|
|
|
'tags' => ['windows'], |
|
381
|
|
|
'last_activity_date' => '2015-01-05', |
|
382
|
|
|
'title' => 'Question about windows #1', |
|
383
|
|
|
]), |
|
384
|
|
|
new Document(4, [ |
|
385
|
|
|
'tags' => ['windows'], |
|
386
|
|
|
'last_activity_date' => '2014-12-23', |
|
387
|
|
|
'title' => 'Question about windows #2', |
|
388
|
|
|
]), |
|
389
|
|
|
new Document(5, [ |
|
390
|
|
|
'tags' => ['osx', 'apple'], |
|
391
|
|
|
'last_activity_date' => '2014-12-23', |
|
392
|
|
|
'title' => 'Question about osx', |
|
393
|
|
|
]), |
|
394
|
|
|
]); |
|
395
|
|
|
|
|
396
|
|
|
$index->refresh(); |
|
397
|
|
|
|
|
398
|
|
|
return $index; |
|
399
|
|
|
} |
|
400
|
|
|
|
|
401
|
|
View Code Duplication |
protected function getOuterAggregationResult($innerAggr) |
|
|
|
|
|
|
402
|
|
|
{ |
|
403
|
|
|
$outerAggr = new Terms('top_tags'); |
|
404
|
|
|
$outerAggr->setField('tags'); |
|
405
|
|
|
$outerAggr->setMinimumDocumentCount(2); |
|
406
|
|
|
$outerAggr->addAggregation($innerAggr); |
|
407
|
|
|
|
|
408
|
|
|
$query = new Query(new MatchAll()); |
|
409
|
|
|
$query->addAggregation($outerAggr); |
|
410
|
|
|
|
|
411
|
|
|
return $this->_getIndexForTest()->search($query)->getAggregation('top_tags'); |
|
412
|
|
|
} |
|
413
|
|
|
} |
|
414
|
|
|
|
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.