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