Skip to content

Commit 2c41813

Browse files
authored
Add sort-abilitiy (#61)
* Update docs, stop using forced keyword * Add fielddata argument for sorting. And sort * Fix the fixture file
1 parent 77a257d commit 2c41813

File tree

7 files changed

+54
-30
lines changed

7 files changed

+54
-30
lines changed

docs/03-Set-up-and-Configuration.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,6 @@ Firesphere\ElasticSearch\Services\ElasticCoreService:
4848
apiKey: MyBase64EncodedApiKeyHere===
4949
```
5050
51-
### Debug
52-
53-
You can force the debugging to false, by setting the debug flag. If you omit this tag, CLI and Dev mode
54-
will have debugging enabled.
55-
5651
#### ShowInSearch
5752
5853
`ShowInSearch` is handled by the module itself, so there is no need to configure it within your YML/PHP index definition.
@@ -68,7 +63,6 @@ There is no effective need for items to be in the search, if they're not suppose
6863
be displayed.
6964

7065
#### Dirty classes
71-
*NOTE* This is currently unfinished
7266

7367
If a change fails to update, a `DirtyClass` is created, recording the need for updating
7468
said object. It is recommended to automatically run the `ClearDirtyClasses` task every few hours
@@ -105,7 +99,6 @@ Firesphere\ElasticSearch\Indexes\ElasticIndex:
10599
Title: TestObject
106100
107101
```
108-
**NOTE** Facets are on to-do
109102

110103
#### MySearchIndex
111104

docs/06-Advanced-Options/01-Faceting.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,9 @@ will result in:
2222

2323
`UserID:1 AND UserID:2 AND Parent:5`
2424

25-
### OR facets
26-
27-
Using OR facets, each facet is treated as a separate part of the query. In the above example,
28-
it would lead to the following query:
29-
30-
`UserID:1 AND UserID:2 OR Parent:5`
31-
3225
## Difference between FacetFields and FacetFilters
3326

34-
- Facet _fields_, are the fields that are expected to be returned by Solr and need to be configured.
27+
- Facet _fields_, are the fields that are expected to be returned by Elastic and need to be configured.
3528
- Facet _filters_, are the actual filters, that are applied at query time, to narrow down the results by the selected Facets.
3629

3730
## Applying facets
@@ -49,7 +42,7 @@ To use AND facets, this example should get you started:
4942
```php
5043
$data = Controller::curr()->getRequest()->getVars();
5144
$index = Injector::inst()->get(MyIndex::class);
52-
$query = Injector::inst()->get(BaseQuery::class);
45+
$query = Injector::inst()->get(ElasticQuery::class);
5346
$facetedFields = $index->getFacetFields();
5447
foreach ($facetedFields as $className => $field) {
5548
// Title of your field, as defined in the FacetFields
@@ -62,7 +55,7 @@ To use AND facets, this example should get you started:
6255

6356
*Note*, `addFacetFilter` and `addAndFacetFilter` are interchangeable.
6457

65-
### OR facets
58+
### OR facets **TODO**
6659

6760
To use OR facets, this example should get you started:
6861

src/Queries/QueryBuilder.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public static function buildQuery(BaseQuery $query, CoreIndex $index): array
4848
$highlights = $self->getHighlighter();
4949
$suggests = $self->getSuggestTermList();
5050
$aggregates = $self->getAggregates();
51+
$sort = $self->getSort();
5152
$body = [];
5253
if (count($terms)) {
5354
$body['query']['bool'] = $terms;
@@ -64,6 +65,9 @@ public static function buildQuery(BaseQuery $query, CoreIndex $index): array
6465
if (count($aggregates)) {
6566
$body['aggs'] = $aggregates;
6667
}
68+
if (count($sort)) {
69+
$body['sort'] = $sort;
70+
}
6771

6872
return [
6973
'index' => $index->getIndexName(),
@@ -273,15 +277,20 @@ private function getSuggestTermList()
273277
return $suggest;
274278
}
275279

276-
public function getAggregates()
280+
/**
281+
* Build the query part for aggregation/faceting
282+
*
283+
* @return array
284+
*/
285+
private function getAggregates()
277286
{
278287
$aggregates = [];
279288

280289
$facets = $this->index->getFacetFields();
281290

282291
foreach ($facets as $class => $facet) {
283292
$shortClass = ClassInfo::shortName($facet['BaseClass']);
284-
$field = sprintf('%s.%s.keyword', $shortClass, $facet['Field']);
293+
$field = sprintf('%s.%s', $shortClass, $facet['Field']);
285294
$aggregates[$facet['Title']] = [
286295
'terms' => [
287296
'field' => $field
@@ -292,4 +301,9 @@ public function getAggregates()
292301

293302
return $aggregates;
294303
}
304+
305+
private function getSort()
306+
{
307+
return $this->query->getSort();
308+
}
295309
}

src/Tasks/ElasticConfigureTask.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ class ElasticConfigureTask extends BuildTask
4040
*/
4141
protected $service;
4242

43+
/**
44+
* DBHTML and DBText etc. should never be made sortable
45+
* It doesn't make sense for large text objects
46+
* @var string[]
47+
*/
48+
private static $unSsortables = [
49+
'HTML',
50+
'Text'
51+
];
52+
4353
/**
4454
* @throws NotFoundExceptionInterface
4555
*/
@@ -108,7 +118,6 @@ protected function configureIndex($instance): Elasticsearch
108118
{
109119
$indexName = $instance->getIndexName();
110120

111-
112121
$instanceConfig = $this->createConfigForIndex($instance);
113122

114123
$mappings = $this->convertForJSON($instanceConfig);
@@ -123,14 +132,15 @@ protected function configureIndex($instance): Elasticsearch
123132
$msg = sprintf($msg, 'Updating', $indexName);
124133
DB::alteration_message($msg);
125134
$this->getLogger()->info($msg);
135+
126136
return $client->indices()->putMapping($body);
127-
} else {
128-
$body['body']['mappings'] = $mappings;
129-
$msg = sprintf($msg, 'Creating', $indexName);
130-
DB::alteration_message($msg);
131-
$this->getLogger()->info($msg);
132-
return $client->indices()->create($body);
133137
}
138+
$body['body']['mappings'] = $mappings;
139+
$msg = sprintf($msg, 'Creating', $indexName);
140+
DB::alteration_message($msg);
141+
$this->getLogger()->info($msg);
142+
143+
return $client->indices()->create($body);
134144
}
135145

136146
/**
@@ -171,6 +181,13 @@ protected function convertForJSON($config)
171181
$base[$conf['name']] = [
172182
'type' => $typeMap[$conf['type'] ?? '*']
173183
];
184+
$shouldHold = true;
185+
foreach (self::$unSsortables as $unSortable) {
186+
$shouldHold = !str_contains($conf['type'], $unSortable) && $shouldHold;
187+
}
188+
if ($shouldHold && $typeMap[$conf['type']] === 'text') {
189+
$base[$conf['name']]['fielddata'] = true;
190+
}
174191
}
175192

176193
return ['properties' => $base];

tests/Fixtures/elasticresponse.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"sum_other_doc_count": 0,
8989
"buckets": [
9090
{
91-
"key": "TestObject",
91+
"key": 1,
9292
"doc_count": 1
9393
}
9494
]
@@ -104,4 +104,4 @@
104104
}
105105
]
106106
}
107-
}
107+
}

tests/unit/Indexes/ElasticIndexTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function testAddSetGet()
5858
$conf['FulltextFields'] = array_merge(
5959
$conf['FulltextFields'] ?? [],
6060
);
61+
$conf['FulltextFields'][] = 'TestObject.ID';
6162
$this->assertEquals($conf['FulltextFields'], $index->getFulltextFields());
6263
$index->addFulltextField('Dummyfield');
6364
$conf['FulltextFields'][] = 'Dummyfield';
@@ -85,7 +86,7 @@ public function testAddSetGet()
8586
$expectedFacets = [
8687
'TestObject' => [
8788
'BaseClass' => 'Page',
88-
'Field' => 'TestObject.Title',
89+
'Field' => 'TestObject.ID',
8990
'Title' => 'TestObject',
9091
]
9192
];

tests/unit/Queries/QueryBuilderTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class QueryBuilderTest extends SapphireTest
6868
'aggs' => [
6969
'TestObject' => [
7070
'terms' => [
71-
'field' => 'Page.TestObject.Title.keyword'
71+
'field' => 'Page.TestObject.ID'
7272
]
7373
]
7474
]
@@ -123,5 +123,11 @@ public function testBuildQuery()
123123
$this->assertEquals('Test', $resultQuery['body']['suggest']['0-partterm']['text']);
124124
$this->assertEquals('Tset', $resultQuery['body']['suggest']['1-partterm']['text']);
125125
$this->assertEquals('Test Tset', $resultQuery['body']['suggest']['1-fullterm']['text']);
126+
127+
$query->setSort(['Title' => 'asc']);
128+
129+
$resultQuery = QueryBuilder::buildQuery($query, $idx);
130+
131+
$this->assertEquals(['Title' => 'asc'], $resultQuery['body']['sort']);
126132
}
127133
}

0 commit comments

Comments
 (0)