1
|
|
|
<?php |
2
|
|
|
use \SilverStripe\Elastica\ElasticSearcher; |
3
|
|
|
use \SilverStripe\Elastica\QueryGenerator; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Test query generation |
7
|
|
|
* @package elastica |
8
|
|
|
*/ |
9
|
|
|
class QueryGeneratorTest extends ElasticsearchBaseTest { |
10
|
|
|
public static $fixture_file = 'elastica/tests/lotsOfPhotos.yml'; |
11
|
|
|
|
12
|
|
|
|
13
|
|
|
public static $ignoreFixtureFileFor = array('testToQuoted*'); |
14
|
|
|
|
15
|
|
|
public function testTextOnly() { |
16
|
|
|
$qg = new QueryGenerator(); |
17
|
|
|
$qg->setQueryText('New Zealand'); |
18
|
|
|
$qg->setFields(null); |
19
|
|
|
$qg->setSelectedFilters(null); |
20
|
|
|
|
21
|
|
|
//As the query is not empty it should not matter whether or not the show results for empty |
22
|
|
|
//query flag is set or not - test with true and false |
23
|
|
|
|
24
|
|
|
$qg->setShowResultsForEmptyQuery(false); |
25
|
|
|
$qs = array('query_string' => array('query' => 'New Zealand', 'lenient' => true)); |
26
|
|
|
$expected = array( |
27
|
|
|
'query' => $qs, |
28
|
|
|
'size' => 10, |
29
|
|
|
'from' => 0, |
30
|
|
|
'suggest' => $this->getDefaultSuggest('New Zealand') |
31
|
|
|
); |
32
|
|
|
|
33
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
34
|
|
|
|
35
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
36
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @param string $queryText |
42
|
|
|
*/ |
43
|
|
|
private function getDefaultSuggest($queryText) { |
44
|
|
|
return array( |
45
|
|
|
'query-phrase-suggestions' => array( |
46
|
|
|
'phrase' => array( |
47
|
|
|
'field' => '_all', |
48
|
|
|
'size' => 4, |
49
|
|
|
'highlight' => array( |
50
|
|
|
'pre_tag' => '<strong class="hl">', |
51
|
|
|
'post_tag' => '</strong>' |
52
|
|
|
) |
53
|
|
|
), |
54
|
|
|
'text' => $queryText |
55
|
|
|
) |
56
|
|
|
); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
|
60
|
|
|
public function testGetQuerySuggester() { |
61
|
|
|
$qg = new QueryGenerator(); |
62
|
|
|
$qg->setQueryText('New Zealand'); |
63
|
|
|
$expected = array('query-suggestions' => array( |
64
|
|
|
'text' => 'New Zealand', |
65
|
|
|
'term' => array('field' => '_all')) |
66
|
|
|
); |
67
|
|
|
$this->assertEquals( |
68
|
|
|
$expected, |
69
|
|
|
$this->getQuerySuggester($qg) |
|
|
|
|
70
|
|
|
); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
|
74
|
|
|
public function testEmptyTextShowNone() { |
75
|
|
|
$qg = new QueryGenerator(); |
76
|
|
|
$qg->setQueryText(''); |
77
|
|
|
$qg->setFields(null); |
78
|
|
|
$qg->setSelectedFilters(null); |
79
|
|
|
$qg->setShowResultsForEmptyQuery(false); |
80
|
|
|
|
81
|
|
|
$qs = array('query_string' => array('query' => '', 'lenient' => true)); |
82
|
|
|
$expected = array( |
83
|
|
|
'query' => $qs, |
84
|
|
|
'size' => 10, |
85
|
|
|
'from' => 0, |
86
|
|
|
'suggest' => $this->getDefaultSuggest('') |
87
|
|
|
); |
88
|
|
|
|
89
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
|
93
|
|
|
public function testEmptyTextShowAll() { |
94
|
|
|
$qg = new QueryGenerator(); |
95
|
|
|
$qg->setQueryText(''); |
96
|
|
|
$qg->setFields(null); |
97
|
|
|
$qg->setSelectedFilters(null); |
98
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
99
|
|
|
|
100
|
|
|
//In order to show all results an empty query works, |
101
|
|
|
//e.g. curl -XGET 'http://localhost:9200/elastica_ss_module_test_en_us/_search?pretty' |
102
|
|
|
$expected = array( |
103
|
|
|
'size' => 10, |
104
|
|
|
'from' => 0, |
105
|
|
|
'suggest' => $this->getDefaultSuggest('') |
106
|
|
|
); |
107
|
|
|
|
108
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
|
112
|
|
View Code Duplication |
public function testMultiMatchWithText() { |
|
|
|
|
113
|
|
|
$qg = new QueryGenerator(); |
114
|
|
|
$qg->setQueryText('New Zealand'); |
115
|
|
|
$fields = array('Title' => 1, 'Description' => 1); |
116
|
|
|
$qg->setFields($fields); |
117
|
|
|
$qg->setSelectedFilters(null); |
118
|
|
|
$qg->setClasses('FlickrPhotoTO'); |
119
|
|
|
|
120
|
|
|
//As the query is not empty it should not matter whether or not the show results for empty |
121
|
|
|
//query flag is set or not - test with true and false |
122
|
|
|
|
123
|
|
|
$qg->setShowResultsForEmptyQuery(false); |
124
|
|
|
$qs = array('multi_match' => array( |
125
|
|
|
'fields' => array('Title','Title.*','Description','Description.*'), |
126
|
|
|
'type' => 'most_fields', |
127
|
|
|
'query' => 'New Zealand', |
128
|
|
|
'lenient' => true |
129
|
|
|
) |
130
|
|
|
); |
131
|
|
|
$expected = array( |
132
|
|
|
'query' => $qs, |
133
|
|
|
'size' => 10, |
134
|
|
|
'from' => 0, |
135
|
|
|
'suggest' => $this->getDefaultSuggest('New Zealand') |
136
|
|
|
); |
137
|
|
|
|
138
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
139
|
|
|
|
140
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
141
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
|
145
|
|
|
|
146
|
|
View Code Duplication |
public function testMultiMatchWithNoText() { |
|
|
|
|
147
|
|
|
$qg = new QueryGenerator(); |
148
|
|
|
$qg->setQueryText(''); |
149
|
|
|
$fields = array('Title' => 1, 'Description' => 1); |
150
|
|
|
$qg->setFields($fields); |
151
|
|
|
$qg->setSelectedFilters(null); |
152
|
|
|
$qg->setClasses('FlickrPhotoTO'); |
153
|
|
|
|
154
|
|
|
//As the query is not empty it should not matter whether or not the show results for empty |
155
|
|
|
//query flag is set or not - test with true and false |
156
|
|
|
|
157
|
|
|
//Case of empty query, do not show results |
158
|
|
|
$qg->setShowResultsForEmptyQuery(false); |
159
|
|
|
$qs = array( |
160
|
|
|
'multi_match' => array( |
161
|
|
|
'fields' => array('Title','Title.*','Description','Description.*'), |
162
|
|
|
'type' => 'most_fields', |
163
|
|
|
'query' => '', |
164
|
|
|
'lenient' => true |
165
|
|
|
) |
166
|
|
|
); |
167
|
|
|
$expected = array( |
168
|
|
|
'query' => $qs, |
169
|
|
|
'size' => 10, |
170
|
|
|
'from' => 0, |
171
|
|
|
'suggest' => $this->getDefaultSuggest('') |
172
|
|
|
); |
173
|
|
|
|
174
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
175
|
|
|
|
176
|
|
|
|
177
|
|
|
// Now the case of empty query and show results |
178
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
179
|
|
|
unset($expected['query']); |
180
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
|
184
|
|
|
// ---- tests with aggregations ---- |
185
|
|
|
|
186
|
|
|
|
187
|
|
|
public function testEmptyTextShowNoResultsWithAggregations() { |
188
|
|
|
$this->assertFalse(false, 'This is not possible - an empty query returns 0 docs and 0 aggregations'); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
|
192
|
|
|
/* |
193
|
|
|
Test aggregations with and without text query |
194
|
|
|
*/ |
195
|
|
|
public function testTextShowResultsWithAggregations() { |
196
|
|
|
$qg = new QueryGenerator(); |
197
|
|
|
$qg->setQueryText(''); |
198
|
|
|
$qg->setFields(null); |
199
|
|
|
$qg->setSelectedFilters(null); |
200
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
201
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
202
|
|
|
$aggs = $this->baseAggs(); |
203
|
|
|
|
204
|
|
|
//tests are complete |
205
|
|
|
$expected = array( |
206
|
|
|
'aggs' => $aggs, |
207
|
|
|
'size' => 10, |
208
|
|
|
'from' => 0, |
209
|
|
|
'sort' => array('TakenAt' => 'desc'), |
210
|
|
|
'suggest' => $this->getDefaultSuggest('') |
211
|
|
|
); |
212
|
|
|
|
213
|
|
|
print_r($qg->generateElasticaQuery()); |
214
|
|
|
|
215
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
216
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
217
|
|
|
|
218
|
|
|
$qg->setQueryText('New Zealand'); |
219
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
220
|
|
|
unset($expected['sort']); |
221
|
|
|
$expected['query'] = array('query_string' => array('query' => 'New Zealand', 'lenient' => true)); |
222
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
223
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
224
|
|
|
|
225
|
|
|
$qg->setShowResultsForEmptyQuery(false); |
226
|
|
|
$qg->setQueryText('New Zealand'); |
227
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
228
|
|
|
$expected['query'] = array('query_string' => array('query' => 'New Zealand', 'lenient' => true)); |
229
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
|
233
|
|
|
/* |
234
|
|
|
Should generate this working query: |
235
|
|
|
curl -XGET 'http://localhost:9200/elastica_ss_module_test_en_us/_search?pretty' -d ' |
236
|
|
|
{ |
237
|
|
|
"query": { |
238
|
|
|
"filtered": { |
239
|
|
|
"filter": { |
240
|
|
|
"term": { |
241
|
|
|
"ISO": 400 |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
}, |
246
|
|
|
"aggs": { |
247
|
|
|
"Aperture": { |
248
|
|
|
"terms": { |
249
|
|
|
"field": "Aperture", |
250
|
|
|
"size": 0, |
251
|
|
|
"order": { |
252
|
|
|
"_term": "asc" |
253
|
|
|
} |
254
|
|
|
} |
255
|
|
|
}, |
256
|
|
|
"ShutterSpeed": { |
257
|
|
|
"terms": { |
258
|
|
|
"field": "ShutterSpeed", |
259
|
|
|
"size": 0, |
260
|
|
|
"order": { |
261
|
|
|
"_term": "asc" |
262
|
|
|
} |
263
|
|
|
} |
264
|
|
|
}, |
265
|
|
|
"FocalLength35mm": { |
266
|
|
|
"terms": { |
267
|
|
|
"field": "FocalLength35mm", |
268
|
|
|
"size": 0, |
269
|
|
|
"order": { |
270
|
|
|
"_term": "asc" |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
}, |
274
|
|
|
"ISO": { |
275
|
|
|
"terms": { |
276
|
|
|
"field": "ISO", |
277
|
|
|
"size": 0, |
278
|
|
|
"order": { |
279
|
|
|
"_term": "asc" |
280
|
|
|
} |
281
|
|
|
} |
282
|
|
|
}, |
283
|
|
|
"Aspect": { |
284
|
|
|
"range": { |
285
|
|
|
"field": "AspectRatio", |
286
|
|
|
"ranges": [{ |
287
|
|
|
"from": 1.0e-7, |
288
|
|
|
"to": 0.3, |
289
|
|
|
"key": "Panoramic" |
290
|
|
|
}, { |
291
|
|
|
"from": 0.3, |
292
|
|
|
"to": 0.9, |
293
|
|
|
"key": "Horizontal" |
294
|
|
|
}, { |
295
|
|
|
"from": 0.9, |
296
|
|
|
"to": 1.2, |
297
|
|
|
"key": "Square" |
298
|
|
|
}, { |
299
|
|
|
"from": 1.2, |
300
|
|
|
"to": 1.79, |
301
|
|
|
"key": "Vertical" |
302
|
|
|
}, { |
303
|
|
|
"from": 1.79, |
304
|
|
|
"to": 10000000, |
305
|
|
|
"key": "Tallest" |
306
|
|
|
}] |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
}, |
310
|
|
|
"size": 10, |
311
|
|
|
"from": 0 |
312
|
|
|
} |
313
|
|
|
' |
314
|
|
|
*/ |
315
|
|
|
public function testTextOneFilterAggregate() { |
316
|
|
|
$qg = new QueryGenerator(); |
317
|
|
|
$qg->setQueryText(''); |
318
|
|
|
$qg->setFields(null); |
319
|
|
|
$filters = array('ISO' => 400); |
320
|
|
|
$qg->setSelectedFilters($filters); |
321
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
322
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
323
|
|
|
$aggs = $this->baseAggs(); |
324
|
|
|
|
325
|
|
|
//FIXME - query needs removed in this case, leave as a reminder for now until |
326
|
|
|
//tests are complete |
327
|
|
|
$expected = array( |
328
|
|
|
'aggs' => $aggs, |
329
|
|
|
'size' => 10, |
330
|
|
|
'from' => 0, |
331
|
|
|
'query' => array( |
332
|
|
|
'filtered' => array( |
333
|
|
|
'filter' => array('term' => array('ISO' => 400)) |
334
|
|
|
) |
335
|
|
|
), |
336
|
|
|
'sort' => array('TakenAt' => 'desc'), |
337
|
|
|
'suggest' => $this->getDefaultSuggest('') |
338
|
|
|
); |
339
|
|
|
|
340
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
341
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
342
|
|
|
|
343
|
|
|
$qg->setQueryText('New Zealand'); |
344
|
|
|
unset($expected['sort']); // use query text search relevance for sorting, ie default Elasticsearch |
345
|
|
|
$expected['query']['filtered']['query']['query_string'] = array('query' => 'New Zealand', 'lenient' => true); |
346
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
347
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
348
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
|
352
|
|
|
public function testTextTwoFilterAggregate() { |
353
|
|
|
$qg = new QueryGenerator(); |
354
|
|
|
$qg->setQueryText(''); |
355
|
|
|
$qg->setFields(null); |
356
|
|
|
$filters = array('ISO' => 400, 'Aspect' => 'Square'); |
357
|
|
|
$qg->setSelectedFilters($filters); |
358
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
359
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
360
|
|
|
$aggs = $this->baseAggs(); |
361
|
|
|
|
362
|
|
|
//FIXME - query needs removed in this case, leave as a reminder for now until |
363
|
|
|
//tests are complete |
364
|
|
|
$expected = array( |
365
|
|
|
'aggs' => $aggs, |
366
|
|
|
'size' => 10, |
367
|
|
|
'from' => 0, |
368
|
|
|
'query' => array( |
369
|
|
|
'filtered' => array( |
370
|
|
|
'filter' => |
371
|
|
|
array('and' => array( |
372
|
|
|
0 => array( 'term' => array('ISO' => 400)), |
373
|
|
|
1 => array( 'range' => array( |
374
|
|
|
'AspectRatio' => array( |
375
|
|
|
'gte' => '0.9', |
376
|
|
|
'lt' => '1.2' |
377
|
|
|
) |
378
|
|
|
)) |
379
|
|
|
) |
380
|
|
|
)) |
381
|
|
|
), |
382
|
|
|
'sort' => array('TakenAt' => 'desc'), |
383
|
|
|
'suggest' => $this->getDefaultSuggest('') |
384
|
|
|
); |
385
|
|
|
|
386
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
387
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
388
|
|
|
|
389
|
|
|
$qg->setQueryText('New Zealand'); |
390
|
|
|
unset($expected['sort']); // use query text search relevance for sorting, ie default Elasticsearch |
391
|
|
|
$expected['query']['filtered']['query']['query_string'] = array('query' => 'New Zealand', 'lenient' => true); |
392
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
393
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
|
397
|
|
|
public function testTextThreeFilterAggregate() { |
398
|
|
|
$qg = new QueryGenerator(); |
399
|
|
|
$qg->setQueryText(''); |
400
|
|
|
$qg->setFields(null); |
401
|
|
|
$filters = array('ISO' => 400, 'Aspect' => 'Square', 'Aperture' => 5.6); |
402
|
|
|
$qg->setSelectedFilters($filters); |
403
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
404
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
405
|
|
|
$aggs = $this->baseAggs(); |
406
|
|
|
|
407
|
|
|
//FIXME - query needs removed in this case, leave as a reminder for now until |
408
|
|
|
//tests are complete |
409
|
|
|
$expected = array( |
410
|
|
|
'aggs' => $aggs, |
411
|
|
|
'size' => 10, |
412
|
|
|
'from' => 0, |
413
|
|
|
'query' => array( |
414
|
|
|
'filtered' => array('filter' => |
415
|
|
|
array('and' => array( |
416
|
|
|
0 => array( 'term' => array('ISO' => 400)), |
417
|
|
|
1 => array( 'range' => array( |
418
|
|
|
'AspectRatio' => array( |
419
|
|
|
'gte' => '0.9', |
420
|
|
|
'lt' => '1.2' |
421
|
|
|
) |
422
|
|
|
)), |
423
|
|
|
2 => array( 'term' => array('Aperture' => 5.6)), |
424
|
|
|
) |
425
|
|
|
)) |
426
|
|
|
), |
427
|
|
|
'sort' => array('TakenAt' => 'desc'), |
428
|
|
|
'suggest' => $this->getDefaultSuggest('') |
429
|
|
|
); |
430
|
|
|
|
431
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
432
|
|
|
|
433
|
|
|
$qg->setQueryText('New Zealand'); |
434
|
|
|
unset($expected['sort']); // use query text search relevance for sorting, ie default Elasticsearch |
435
|
|
|
$expected['query']['filtered']['query']['query_string'] = array('query' => 'New Zealand', 'lenient' => true); |
436
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
437
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
|
441
|
|
|
public function testMultiMatchOneFilterAggregate() { |
442
|
|
|
$qg = new QueryGenerator(); |
443
|
|
|
$qg->setQueryText(''); |
444
|
|
|
$qg->setFields(array('Title' => 2, 'Content' => 1)); |
445
|
|
|
$filters = array('ISO' => 400); |
446
|
|
|
$qg->setSelectedFilters($filters); |
447
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
448
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
449
|
|
|
$aggs = $this->baseAggs(); |
450
|
|
|
|
451
|
|
|
//FIXME - query needs removed in this case, leave as a reminder for now until |
452
|
|
|
//tests are complete |
453
|
|
|
$expected = array( |
454
|
|
|
'aggs' => $aggs, |
455
|
|
|
'size' => 10, |
456
|
|
|
'from' => 0, |
457
|
|
|
'query' => array( |
458
|
|
|
'filtered' => array( |
459
|
|
|
'filter' => array('term' => array('ISO' => 400)) |
460
|
|
|
) |
461
|
|
|
), |
462
|
|
|
'sort' => array('TakenAt' => 'desc'), |
463
|
|
|
'suggest' => $this->getDefaultSuggest('') |
464
|
|
|
); |
465
|
|
|
|
466
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
467
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
468
|
|
|
|
469
|
|
|
$qg->setQueryText('New Zealand'); |
470
|
|
|
unset($expected['sort']); // use relevance of search sorting |
471
|
|
|
|
472
|
|
|
$expected['query']['filtered']['query']['multi_match'] = array( |
473
|
|
|
'query' => 'New Zealand', |
474
|
|
|
'lenient' => true, |
475
|
|
|
'fields' => array('Title^2', 'Title.*^2','Content', 'Content.*'), |
476
|
|
|
'type' => 'most_fields' |
477
|
|
|
); |
478
|
|
|
|
479
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
480
|
|
|
print_r($qg->generateElasticaQuery()->toArray()); |
481
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
|
485
|
|
|
|
486
|
|
|
public function testMultiMatchTwoFilterAggregate() { |
487
|
|
|
$qg = new QueryGenerator(); |
488
|
|
|
$qg->setQueryText(''); |
489
|
|
|
$qg->setFields(array('Title' => 2, 'Content' => 1)); |
490
|
|
|
$filters = array('ISO' => 400, 'Aspect' => 'Square'); |
491
|
|
|
$qg->setSelectedFilters($filters); |
492
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
493
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
494
|
|
|
$aggs = $this->baseAggs(); |
495
|
|
|
|
496
|
|
|
//FIXME - query needs removed in this case, leave as a reminder for now until |
497
|
|
|
//tests are complete |
498
|
|
|
$expected = array( |
499
|
|
|
'aggs' => $aggs, |
500
|
|
|
'size' => 10, |
501
|
|
|
'from' => 0, |
502
|
|
|
'query' => array( |
503
|
|
|
'filtered' => array( |
504
|
|
|
'filter' => |
505
|
|
|
array('and' => array( |
506
|
|
|
0 => array( 'term' => array('ISO' => 400)), |
507
|
|
|
1 => array( 'range' => array( |
508
|
|
|
'AspectRatio' => array( |
509
|
|
|
'gte' => '0.9', |
510
|
|
|
'lt' => '1.2' |
511
|
|
|
) |
512
|
|
|
)) |
513
|
|
|
) |
514
|
|
|
)) |
515
|
|
|
), |
516
|
|
|
'sort' => array('TakenAt' => 'desc'), |
517
|
|
|
'suggest' => $this->getDefaultSuggest('') |
518
|
|
|
); |
519
|
|
|
|
520
|
|
|
echo(json_encode($qg->generateElasticaQuery()->toArray())); |
521
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
522
|
|
|
|
523
|
|
|
$qg->setQueryText('New Zealand'); |
524
|
|
|
unset($expected['sort']); // use relevance of search sorting |
525
|
|
|
$expected['query']['filtered']['query']['multi_match'] = array( |
526
|
|
|
'query' => 'New Zealand', |
527
|
|
|
'lenient' => true, |
528
|
|
|
'fields' => array('Title^2', 'Title.*^2','Content', 'Content.*'), |
529
|
|
|
'type' => 'most_fields' |
530
|
|
|
); |
531
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
532
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
|
536
|
|
|
|
537
|
|
|
public function testMultiMatchThreeFilterAggregate() { |
538
|
|
|
$qg = new QueryGenerator(); |
539
|
|
|
$qg->setQueryText(''); |
540
|
|
|
$qg->setFields(array('Title' => 2, 'Content' => 1)); |
541
|
|
|
$filters = array('ISO' => 400, 'Aspect' => 'Square', 'Aperture' => 5.6); |
542
|
|
|
$qg->setSelectedFilters($filters); |
543
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
544
|
|
|
$qg->setQueryResultManipulator('FlickrPhotoTOElasticaSearchHelper'); |
545
|
|
|
$aggs = $this->baseAggs(); |
546
|
|
|
|
547
|
|
|
//FIXME - query needs removed in this case, leave as a reminder for now until |
548
|
|
|
//tests are complete |
549
|
|
|
$expected = array( |
550
|
|
|
'aggs' => $aggs, |
551
|
|
|
'size' => 10, |
552
|
|
|
'from' => 0, |
553
|
|
|
'query' => array( |
554
|
|
|
'filtered' => array('filter' => |
555
|
|
|
array('and' => array( |
556
|
|
|
0 => array( 'term' => array('ISO' => 400)), |
557
|
|
|
1 => array( 'range' => array( |
558
|
|
|
'AspectRatio' => array( |
559
|
|
|
'gte' => '0.9', |
560
|
|
|
'lt' => '1.2' |
561
|
|
|
) |
562
|
|
|
)), |
563
|
|
|
2 => array( 'term' => array('Aperture' => 5.6)), |
564
|
|
|
) |
565
|
|
|
)) |
566
|
|
|
), |
567
|
|
|
'sort' => array('TakenAt' => 'desc'), |
568
|
|
|
'suggest' => $this->getDefaultSuggest('') |
569
|
|
|
); |
570
|
|
|
|
571
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
572
|
|
|
|
573
|
|
|
$qg->setQueryText('New Zealand'); |
574
|
|
|
unset($expected['sort']); |
575
|
|
|
$expected['query']['filtered']['query']['multi_match'] = array( |
576
|
|
|
'query' => 'New Zealand', |
577
|
|
|
'lenient' => true, |
578
|
|
|
'fields' => array('Title^2', 'Title.*^2','Content', 'Content.*'), |
579
|
|
|
'type' => 'most_fields' |
580
|
|
|
); |
581
|
|
|
$expected['suggest'] = $this->getDefaultSuggest('New Zealand'); |
582
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
|
586
|
|
|
|
587
|
|
|
|
588
|
|
|
// ---- tests for field array to elasticsearch syntax |
589
|
|
View Code Duplication |
public function testConvertWeightedFieldsForElasticaUnaryStrings() { |
|
|
|
|
590
|
|
|
$qg = new QueryGenerator(); |
591
|
|
|
$qg->setClasses('FlickrPhotoTO'); |
592
|
|
|
$fields = array('Title' => 1, 'Description' => 1); |
593
|
|
|
$expected = array('Title', 'Title.*','Description', 'Description.*'); |
594
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
|
598
|
|
View Code Duplication |
public function testConvertWeightedFieldsForElasticaMultipleStrings() { |
|
|
|
|
599
|
|
|
$qg = new QueryGenerator(); |
600
|
|
|
$qg->setClasses('FlickrPhotoTO'); |
601
|
|
|
$fields = array('Title' => 2, 'Description' => 1); |
602
|
|
|
$expected = array('Title^2', 'Title.*^2','Description', 'Description.*'); |
603
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
|
607
|
|
|
public function testConvertWeightedFieldsForElasticaTestNonString() { |
608
|
|
|
$qg = new QueryGenerator(); |
609
|
|
|
$qg->setClasses('FlickrPhotoTO'); |
610
|
|
|
$fields = array('Aperture' => 2, 'FocalLength35mm' => 1); |
611
|
|
|
$expected = array('Aperture^2', 'FocalLength35mm'); |
612
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
|
616
|
|
|
public function testConvertWeightedFieldsForElasticaNonExistent() { |
617
|
|
|
$qg = new QueryGenerator(); |
618
|
|
|
$qg->setClasses('FlickrPhotoTO'); |
619
|
|
|
$fields = array('Aperture' => 2, 'FocalLength35mm' => 1, 'Wibble' => 2); |
620
|
|
|
try { |
621
|
|
|
$this->assertEquals('This test should fail', $qg->convertWeightedFieldsForElastica($fields)); |
622
|
|
|
$this->fail('An exception should have been thrown as the field Wibble does not exist'); |
623
|
|
|
} catch (Exception $e) { |
624
|
|
|
$this->assertEquals('Field Wibble does not exist', $e->getMessage()); |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
} |
628
|
|
|
|
629
|
|
|
|
630
|
|
View Code Duplication |
public function testSearchFieldsMappingForClasses() { |
|
|
|
|
631
|
|
|
$qg = new QueryGenerator(); |
632
|
|
|
$qg->setClasses('FlickrPhotoTO,Page'); |
633
|
|
|
$fields = array('Title' => 2, 'Description' => 1); |
634
|
|
|
$expected = array('Title^2', 'Title.*^2','Description', 'Description.*'); |
635
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
636
|
|
|
|
637
|
|
|
$qg->setClasses(array('FlickrPhotoTO','Page')); |
|
|
|
|
638
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
639
|
|
|
|
640
|
|
|
} |
641
|
|
|
|
642
|
|
|
|
643
|
|
|
public function testSearchFieldsMappingForClassesCaching() { |
644
|
|
|
QueryGenerator::resetCacheHitCounter(); |
645
|
|
|
$cache = SS_Cache::factory('elasticsearch'); |
646
|
|
|
// Previous tests may have altered this so start from a known position |
647
|
|
|
$cache->remove('SEARCHABLE_FIELDS_FlickrPhotoTO_Page'); |
648
|
|
|
$qg = new QueryGenerator(); |
649
|
|
|
$qg->setClasses('FlickrPhotoTO,Page'); |
650
|
|
|
$fields = array('Title' => 2, 'Description' => 1); |
651
|
|
|
$expected = array('Title^2', 'Title.*^2','Description', 'Description.*'); |
652
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
653
|
|
|
|
654
|
|
|
//Execute a 2nd time |
655
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
656
|
|
|
//Check for cache hit |
657
|
|
|
$this->assertEquals(1, QueryGenerator::getCacheHitCounter()); |
658
|
|
|
|
659
|
|
|
//Execute a 3rd time |
660
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
661
|
|
|
//Check for cache hit |
662
|
|
|
$this->assertEquals(2, QueryGenerator::getCacheHitCounter()); |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
|
666
|
|
View Code Duplication |
public function testSearchFieldsMappingForSiteTree() { |
|
|
|
|
667
|
|
|
$qg = new QueryGenerator(); |
668
|
|
|
$qg->setClasses(null); // select all of site tree classes |
669
|
|
|
$fields = array('Title' => 2, 'Content' => 1); |
670
|
|
|
$expected = array('Title^2', 'Title.*^2','Content', 'Content.*'); |
671
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
672
|
|
|
|
673
|
|
|
echo "--------------------\n"; |
674
|
|
|
$qg->setClasses(array('FlickrPhotoTO','Page')); |
|
|
|
|
675
|
|
|
$this->assertEquals($expected, $qg->convertWeightedFieldsForElastica($fields)); |
676
|
|
|
|
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
|
680
|
|
|
public function testPagination() { |
681
|
|
|
$qg = new QueryGenerator(); |
682
|
|
|
$qg->setQueryText('New Zealand'); |
683
|
|
|
$qg->setFields(null); |
684
|
|
|
$qg->setSelectedFilters(null); |
685
|
|
|
$qg->setPageLength(12); |
686
|
|
|
$qg->setStart(24); |
687
|
|
|
|
688
|
|
|
//As the query is not empty it should not matter whether or not the show results for empty |
689
|
|
|
//query flag is set or not - test with true and false |
690
|
|
|
|
691
|
|
|
$qg->setShowResultsForEmptyQuery(false); |
692
|
|
|
$this->assertEquals(false, $qg->getShowResultsForEmptyQuery()); |
693
|
|
|
$qs = array('query_string' => array('query' => 'New Zealand', 'lenient' => true)); |
694
|
|
|
$expected = array( |
695
|
|
|
'query' => $qs, |
696
|
|
|
'size' => 12, |
697
|
|
|
'from' => 24, |
698
|
|
|
'suggest' => $this->getDefaultSuggest('New Zealand') |
699
|
|
|
); |
700
|
|
|
|
701
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
702
|
|
|
|
703
|
|
|
$qg->setShowResultsForEmptyQuery(true); |
704
|
|
|
$this->assertEquals(true, $qg->getShowResultsForEmptyQuery()); |
705
|
|
|
$this->assertEquals($expected, $qg->generateElasticaQuery()->toArray()); |
706
|
|
|
} |
707
|
|
|
|
708
|
|
|
|
709
|
|
|
/** |
710
|
|
|
* Get an array to be used as a query for Elastica |
711
|
|
|
* @return array Building bricks for a query suggester |
712
|
|
|
*/ |
713
|
|
|
private function getQuerySuggester() { |
714
|
|
|
$suggester = array(); |
715
|
|
|
$suggester['text'] = $this->queryText; |
|
|
|
|
716
|
|
|
|
717
|
|
|
//With _all field enable in the mapping, Searchable.php class, we can use _all field to |
718
|
|
|
//suggest against all fields. It is not possible to pass an array here |
719
|
|
|
$suggester['term'] = array('field' => '_all'); |
720
|
|
|
$querySuggester = array('query-suggestions' => $suggester); |
721
|
|
|
|
722
|
|
|
return $querySuggester; |
723
|
|
|
} |
724
|
|
|
|
725
|
|
|
|
726
|
|
|
|
727
|
|
|
/** |
728
|
|
|
* Get the basic aggregates that should be returned for the augmenter being tested |
729
|
|
|
* @return array array of aggregations. Tweak these in tests and assert as required. |
730
|
|
|
*/ |
731
|
|
|
private function baseAggs() { |
732
|
|
|
$result = array(); |
733
|
|
|
$result['Aperture'] = array( |
734
|
|
|
'terms' => array( |
735
|
|
|
'field' => 'Aperture', |
736
|
|
|
'size' => 0, |
737
|
|
|
'order' => array('_term' => 'asc') |
738
|
|
|
) |
739
|
|
|
); |
740
|
|
|
$result['ShutterSpeed'] = array( |
741
|
|
|
'terms' => array( |
742
|
|
|
'field' => 'ShutterSpeed', |
743
|
|
|
'size' => 0, |
744
|
|
|
'order' => array('_term' => 'asc') |
745
|
|
|
) |
746
|
|
|
); |
747
|
|
|
$result['FocalLength35mm'] = array( |
748
|
|
|
'terms' => array( |
749
|
|
|
'field' => 'FocalLength35mm', |
750
|
|
|
'size' => 0, |
751
|
|
|
'order' => array('_term' => 'asc') |
752
|
|
|
) |
753
|
|
|
); |
754
|
|
|
$result['ISO'] = array( |
755
|
|
|
'terms' => array( |
756
|
|
|
'field' => 'ISO', |
757
|
|
|
'size' => 0, |
758
|
|
|
'order' => array('_term' => 'asc') |
759
|
|
|
) |
760
|
|
|
); |
761
|
|
|
|
762
|
|
|
$ranges = array(); |
763
|
|
|
$ranges[0] = array('from' => '1.0E-7', 'to' => '0.3', 'key' => 'Panoramic'); |
764
|
|
|
$ranges[1] = array('from' => '0.3', 'to' => '0.9', 'key' => 'Horizontal'); |
765
|
|
|
$ranges[2] = array('from' => '0.9', 'to' => '1.2', 'key' => 'Square'); |
766
|
|
|
$ranges[3] = array('from' => '1.2', 'to' => '1.79', 'key' => 'Vertical'); |
767
|
|
|
$ranges[4] = array('from' => '1.79', 'to' => '10000000', 'key' => 'Tallest'); |
768
|
|
|
|
769
|
|
|
$result['Aspect'] = array( |
770
|
|
|
'range' => array( |
771
|
|
|
'field' => 'AspectRatio', |
772
|
|
|
'ranges' => $ranges |
773
|
|
|
) |
774
|
|
|
); |
775
|
|
|
return $result; |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
|
779
|
|
|
// ---- tests for the toQuotedCSV function ---- |
780
|
|
|
public function testToQuotedCSVFromString() { |
781
|
|
|
$expected = "'Bangkok','Nonthaburi','Saraburi','Chiang Mai'"; |
782
|
|
|
$items = 'Bangkok,Nonthaburi,Saraburi,Chiang Mai'; |
783
|
|
|
$quoted = QueryGenerator::convertToQuotedCSV($items); |
784
|
|
|
$this->assertEquals($expected, $quoted); |
785
|
|
|
} |
786
|
|
|
|
787
|
|
|
public function testToQuotedCSVFromArray() { |
788
|
|
|
$expected = "'Bangkok','Nonthaburi','Saraburi','Chiang Mai'"; |
789
|
|
|
$items = array('Bangkok','Nonthaburi','Saraburi','Chiang Mai'); |
790
|
|
|
$quoted = QueryGenerator::convertToQuotedCSV($items); |
791
|
|
|
$this->assertEquals($expected, $quoted); |
792
|
|
|
} |
793
|
|
|
|
794
|
|
|
public function testToQuotedCSVEmptyString() { |
795
|
|
|
$quoted = QueryGenerator::convertToQuotedCSV(''); |
796
|
|
|
$this->assertEquals('', $quoted); |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
public function testToQuotedCSVEmptyArray() { |
800
|
|
|
$quoted = QueryGenerator::convertToQuotedCSV(array()); |
801
|
|
|
$this->assertEquals('', $quoted); |
802
|
|
|
} |
803
|
|
|
|
804
|
|
|
public function testToQuotedCSVNull() { |
805
|
|
|
$quoted = QueryGenerator::convertToQuotedCSV(null); |
806
|
|
|
$this->assertEquals('', $quoted); |
807
|
|
|
} |
808
|
|
|
} |
809
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.