Skip to content

Commit 4f7c447

Browse files
committed
feat(elastic): add the ability to configure the elastic index
1 parent 0dd9c6c commit 4f7c447

7 files changed

Lines changed: 158 additions & 49 deletions

File tree

DependencyInjection/Configuration.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ public function getConfigTreeBuilder()
134134
->defaultNull()
135135
->info('This option allows you to use namespaced Elasticsearch indexes (format "{prefix}_{corpus}"')
136136
->end()
137+
->arrayNode('configuration')
138+
->useAttributeAsKey('corpus')
139+
->arrayPrototype()
140+
->children()
141+
->scalarNode('settings')->info('absolute path to a JSON settings file')->end()
142+
->scalarNode('mappings')->info('absolute path to a JSON mappings file')->end()
143+
->end()
144+
->end()
145+
->end()
137146
->end()
138147
->end()
139148
->end();

DependencyInjection/MarkupNeedleExtension.php

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
namespace Markup\NeedleBundle\DependencyInjection;
44

5+
use Markup\Json\Encoder;
56
use Markup\NeedleBundle\Builder\QueryBuildOptions;
67
use Markup\NeedleBundle\Builder\QueryBuildOptionsLocator;
78
use Markup\NeedleBundle\Client\BackendClientServiceLocator;
89
use Markup\NeedleBundle\Context\ConfiguredContextProvider;
910
use Markup\NeedleBundle\Corpus\CorpusBackendProvider;
11+
use Markup\NeedleBundle\Elastic\CorpusIndexConfiguration;
1012
use Markup\NeedleBundle\Elastic\CorpusIndexProvider;
1113
use Markup\NeedleBundle\Intercept\Definition as InterceptDefinition;
1214
use Markup\NeedleBundle\Intercept\NormalizedListMatcher;
1315
use Markup\NeedleBundle\Suggest\SuggestHandlerLocator;
14-
use Markup\NeedleBundle\Terms\TermsFieldProviderInterface;
1516
use Markup\NeedleBundle\Terms\TermsFieldProviderLocator;
1617
use Symfony\Component\Config\FileLocator;
1718
use Symfony\Component\DependencyInjection\ChildDefinition;
@@ -55,7 +56,7 @@ public function load(array $configs, ContainerBuilder $container)
5556
/**
5657
* Loads the debug flag.
5758
*
58-
* @param array $config
59+
* @param array $config
5960
* @param ContainerBuilder $container
6061
**/
6162
private function loadDebug(array $config, ContainerBuilder $container)
@@ -66,7 +67,7 @@ private function loadDebug(array $config, ContainerBuilder $container)
6667
/**
6768
* Loads information about the corpora.
6869
*
69-
* @param array $config
70+
* @param array $config
7071
* @param ContainerBuilder $container
7172
**/
7273
private function loadCorpora(array $config, ContainerBuilder $container)
@@ -78,14 +79,16 @@ private function loadCorpora(array $config, ContainerBuilder $container)
7879
$container->setParameter('markup_needle.schedule_events_by_corpus', $scheduleEvents);
7980
//define client service locator
8081
$clientLocator = (new Definition(BackendClientServiceLocator::class))
81-
->setArguments([
82-
array_map(
83-
function (array $corpusConfig) {
84-
return new Reference($corpusConfig['backend']['client']);
85-
},
86-
$config['corpora']
87-
)
88-
])
82+
->setArguments(
83+
[
84+
array_map(
85+
function (array $corpusConfig) {
86+
return new Reference($corpusConfig['backend']['client']);
87+
},
88+
$config['corpora']
89+
),
90+
]
91+
)
8992
->setPublic(false)
9093
->addTag('container.service_locator');
9194
$container->setDefinition(BackendClientServiceLocator::class, $clientLocator);
@@ -107,47 +110,55 @@ function (array $corpusConfig) {
107110
);
108111
$container->setParameter('markup_needle.terms_service_lookup', $termsServiceLookup);
109112
$suggestHandlerLocator = (new Definition(SuggestHandlerLocator::class))
110-
->setArguments([
111-
array_map(
112-
function (array $corpusConfig) {
113-
return new Reference($corpusConfig['suggest_handler']);
114-
},
115-
$config['corpora']
116-
)
117-
])
113+
->setArguments(
114+
[
115+
array_map(
116+
function (array $corpusConfig) {
117+
return new Reference($corpusConfig['suggest_handler']);
118+
},
119+
$config['corpora']
120+
),
121+
]
122+
)
118123
->setPublic(false)
119124
->addTag('container.service_locator');
120125
$container->setDefinition(SuggestHandlerLocator::class, $suggestHandlerLocator);
121126
$termsFieldProviderLocator = (new Definition(TermsFieldProviderLocator::class))
122-
->setArguments([
123-
array_map(
124-
function (array $corpusConfig) {
125-
return new Reference($corpusConfig['terms_field_provider']);
126-
},
127-
$config['corpora']
128-
)
129-
])
127+
->setArguments(
128+
[
129+
array_map(
130+
function (array $corpusConfig) {
131+
return new Reference($corpusConfig['terms_field_provider']);
132+
},
133+
$config['corpora']
134+
),
135+
]
136+
)
130137
->setPublic(false)
131138
->addTag('container.service_locator');
132139
$container->setDefinition(TermsFieldProviderLocator::class, $termsFieldProviderLocator);
133140
$queryBuildOptionsLocator = (new Definition(QueryBuildOptionsLocator::class))
134-
->setArguments([
135-
array_map(
136-
function (array $corpusConfig) use ($container) {
137-
$options = (new Definition(QueryBuildOptions::class))
138-
->setArguments([
139-
[
140-
'useWildcardSearch' => $corpusConfig['use_wildcard_search'],
141-
],
142-
]);
143-
$optionsId = 'markup_needle.query_build_options'.strval(rand());
144-
$container->setDefinition($optionsId, $options);
145-
146-
return new Reference($optionsId);
147-
},
148-
$config['corpora']
149-
)
150-
])
141+
->setArguments(
142+
[
143+
array_map(
144+
function (array $corpusConfig) use ($container) {
145+
$options = (new Definition(QueryBuildOptions::class))
146+
->setArguments(
147+
[
148+
[
149+
'useWildcardSearch' => $corpusConfig['use_wildcard_search'],
150+
],
151+
]
152+
);
153+
$optionsId = 'markup_needle.query_build_options'.strval(rand());
154+
$container->setDefinition($optionsId, $options);
155+
156+
return new Reference($optionsId);
157+
},
158+
$config['corpora']
159+
),
160+
]
161+
)
151162
->setPublic(false)
152163
->addTag('container.service_locator');
153164
$container->setDefinition(QueryBuildOptionsLocator::class, $queryBuildOptionsLocator);
@@ -156,7 +167,7 @@ function (array $corpusConfig) use ($container) {
156167
/**
157168
* Loads the definitions for search intercepts.
158169
*
159-
* @param array $config
170+
* @param array $config
160171
* @param ContainerBuilder $container
161172
**/
162173
private function loadIntercepts(array $config, ContainerBuilder $container)
@@ -196,7 +207,7 @@ private function loadIntercepts(array $config, ContainerBuilder $container)
196207
}
197208

198209
/**
199-
* @param array $config
210+
* @param array $config
200211
* @param ContainerBuilder $container
201212
**/
202213
private function loadLogSettings(array $config, ContainerBuilder $container)
@@ -216,7 +227,10 @@ private function loadContextServices(array $config, ContainerBuilder $container)
216227
$prefix = sprintf('markup_needle.contexts.%s.', $contextName);
217228
$container->setAlias($prefix.'filter_provider', $contextConfig['filter_provider']);
218229
$container->setAlias($prefix.'facet_provider', $contextConfig['facet_provider']);
219-
$container->setAlias($prefix.'facet_set_decorator_provider', $contextConfig['facet_set_decorator_provider']);
230+
$container->setAlias(
231+
$prefix.'facet_set_decorator_provider',
232+
$contextConfig['facet_set_decorator_provider']
233+
);
220234
$container->setAlias($prefix.'facet_collator_provider', $contextConfig['facet_collator_provider']);
221235
$container->setAlias($prefix.'facet_order_provider', $contextConfig['facet_order_provider']);
222236
$contextProvider = new Definition(
@@ -236,6 +250,24 @@ private function loadContextServices(array $config, ContainerBuilder $container)
236250

237251
private function loadBackendSpecificServices(array $config, ContainerBuilder $container)
238252
{
253+
$settings = [];
254+
$mappings = [];
255+
256+
foreach ($config['elasticsearch']['configuration'] as $corpus => $configuration) {
257+
try {
258+
$settings[$corpus] = Encoder::decode(strval(file_get_contents($configuration['settings'])), true);
259+
$mappings[$corpus] = Encoder::decode(strval(file_get_contents($configuration['mappings'])), true);
260+
} catch (\JsonException $e) {
261+
throw new \LogicException(
262+
sprintf('Invalid JSON in elastic configuration files (%s)', implode(', ', $configuration))
263+
);
264+
}
265+
}
266+
267+
$corpusIndexConfiguration = $container->findDefinition(CorpusIndexConfiguration::class);
268+
$corpusIndexConfiguration->setArgument('$settings', $settings);
269+
$corpusIndexConfiguration->setArgument('$mappings', $mappings);
270+
239271
$corpusIndexProvider = $container->getDefinition(CorpusIndexProvider::class);
240272
$corpusIndexProvider->setArgument('$prefix', $config['elasticsearch']['index_prefix']);
241273
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Markup\NeedleBundle\Elastic;
5+
6+
/**
7+
* A corpus keyed array of mappings and settings by Corpus
8+
*/
9+
class CorpusIndexConfiguration
10+
{
11+
/**
12+
* @var array
13+
*/
14+
private $settings;
15+
16+
/**
17+
* @var array
18+
*/
19+
private $mappings;
20+
21+
public function __construct(?array $settings = null, ?array $mappings = null)
22+
{
23+
$this->settings = $settings ?: [];
24+
$this->mappings = $mappings ?: [];
25+
}
26+
27+
public function getSettings(string $corpus): array
28+
{
29+
return $this->settings[$corpus] ?? [];
30+
}
31+
32+
public function getMappings(string $corpus): array
33+
{
34+
return $this->mappings[$corpus] ?? [];
35+
}
36+
}

Indexer/ElasticsearchIndexingMessager.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Elasticsearch\Client;
88
use Elasticsearch\Common\Exceptions\Missing404Exception;
9+
use Markup\NeedleBundle\Elastic\CorpusIndexConfiguration;
910
use Markup\NeedleBundle\Elastic\CorpusIndexProvider;
1011
use Markup\NeedleBundle\Elastic\QueryShapeBuilder;
1112

@@ -28,14 +29,21 @@ class ElasticsearchIndexingMessager implements IndexingMessagerInterface
2829
*/
2930
private $corpusIndexProvider;
3031

32+
/**
33+
* @var CorpusIndexConfiguration
34+
*/
35+
private $corpusIndexConfiguration;
36+
3137
public function __construct(
3238
Client $elastic,
3339
SubjectDataMapperProvider $dataMapperProvider,
34-
CorpusIndexProvider $corpusIndexProvider
40+
CorpusIndexProvider $corpusIndexProvider,
41+
CorpusIndexConfiguration $corpusIndexConfiguration
3542
) {
3643
$this->elastic = $elastic;
3744
$this->dataMapperProvider = $dataMapperProvider;
3845
$this->corpusIndexProvider = $corpusIndexProvider;
46+
$this->corpusIndexConfiguration = $corpusIndexConfiguration;
3947
}
4048

4149
public function executeIndex(
@@ -53,6 +61,24 @@ public function executeIndex(
5361
} catch (Missing404Exception $e) {
5462
//the index didn't previously exist, but that's OK
5563
}
64+
65+
$body = [];
66+
$settings = $this->corpusIndexConfiguration->getSettings($message->getCorpus());
67+
$mappings = $this->corpusIndexConfiguration->getMappings($message->getCorpus());
68+
69+
if (!empty($settings)) {
70+
$body['settings'] = $settings;
71+
}
72+
if (!empty($mappings)) {
73+
$body['mappings'] = $mappings;
74+
}
75+
76+
$this->elastic->indices()->create(
77+
[
78+
'index' => $index,
79+
'body' => $body
80+
]
81+
);
5682
} elseif ($preDeleteQuery !== null) {
5783
$this->elastic->deleteByQuery(
5884
[

Resources/config/services.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,6 @@ services:
166166
arguments:
167167
- ~
168168
public: false
169+
170+
Markup\NeedleBundle\Elastic\CorpusIndexConfiguration:
171+
public: false

Tests/Indexer/ElasticsearchIndexingMessagerTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tests\Indexer;
44

55
use Elasticsearch\Client;
6+
use Markup\NeedleBundle\Elastic\CorpusIndexConfiguration;
67
use Markup\NeedleBundle\Elastic\CorpusIndexProvider;
78
use Markup\NeedleBundle\Indexer\ElasticsearchIndexingMessager;
89
use Markup\NeedleBundle\Indexer\IndexingMessagerInterface;
@@ -34,7 +35,8 @@ protected function setUp()
3435
$this->messager = new ElasticsearchIndexingMessager(
3536
$this->elastic,
3637
$this->subjectDataMapperProvider,
37-
new CorpusIndexProvider(null)
38+
new CorpusIndexProvider(null),
39+
new CorpusIndexConfiguration()
3840
);
3941
}
4042

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"pagerfanta/pagerfanta": "~1.0.1",
2121
"symfony/framework-bundle": "^3.4|^4",
2222
"twig/twig": "~1.12|~2.0",
23+
"markup/json": "^0.1",
2324
"doctrine/collections": "^1.5",
2425
"doctrine/orm": "^2.4"
2526
},

0 commit comments

Comments
 (0)