I am currently in the process of trying to have the date fields for the entries in our database treated as 'text' in the Elasticsearch index. I would like to do this by the addition of a 'mappings' field to the body of the index creation command but have run into a series of increasingly frustrating issue over the past few days while I've tried to get this working.
The project that is using this search will be used is coded in php and uses the Laravel framework. The project uses Laravel Scout and I have created a custom driver in order to extend Scout to use an Elasticsearch implementation.
Additionally, I have added a command to php artisan that allows for the creation of Elasticsearch indices. This command class has default analysis and filters but can also check on a per-model basis if the model for which an index being create has custom analysis, filters, or mappings defined and merges parts of the array accordingly.
In this case, the mappings that I would like to use for the index is:
'mappings' => [
'date_detection' => 'false',
'properties' => [
'startdate' => [
'type' => 'text'
]
]
]
This did not work. Initially when I was just flushing the index (which normally uses Artisan::call to recreate the the index of the model being flushed automatically) and reimporting the mapping wouldn't change at all and I would run into errors because I was attempting to query text on a field that was a 'date' in 'epoch_milis' format. When I tried separating out the flush and the index creation, the index would be created with the updated mapping but would cause an error when I tried to import documents:
Elasticsearch\Common\Exceptions\BadRequest400Exception
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Rejecting mapping update to [registrations] as the final mapping would have more than 1 type: [_doc, registrations]"}],"type":"illegal_argument_exception","reason":"Rejecting mapping update to [registrations] as the final mapping would have more than 1 type: [_doc, registrations]"},"status":400}
at vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php:632
628| $exception = new ScriptLangNotSupportedException($responseBody. $statusCode);
629| } elseif ($statusCode === 408) {
630| $exception = new RequestTimeout408Exception($responseBody, $statusCode);
631| } else {
> 632| $exception = new BadRequest400Exception($responseBody, $statusCode);
633| }
634|
635| $this->logRequestFail($request, $response, $exception);
636|
+9 vendor frames
10 app/Engines/ElasticSearchEngine.php:33
Elasticsearch\Client::index([])
+1 vendor frames
12 app/Engines/ElasticSearchEngine.php:34
Illuminate\Support\Collection::each(Object(Closure))
I tried setting the mapping to 'dynamic' => false
so that the mapping wouldn't update when the documents were being index due to not having all of the fields in the custom mapping that I had defined and I got the same error. I tried adding all of the fields to the mapping exactly as they appeared when I checked the mapping after it was automatically generated when I didn't define a custom mapping and only changing the property of the 'star date' field and I got the same error. I even tried copying the mapping exactly as it appeared when I let it be automatically generated so that the document indexing would have no reason to update the mapping both with and without setting dynamic mapping to false and got the same error.
For the relevant parts of the code the handle() of the creation index command looks like:
if (!class_exists($model = $this->argument('model'))) {
return $this->error("No such model, {$model}, exists");
}
$model = new $model;
try {
$this->client->indices()->create([
'index' => $model->searchableAs(),
'body' => array_merge([
'settings' => [
'index' => [
'analysis' => [
'filter' => $this->getFilters($model),
'analyzer' => $this->getAnalyzers($model)
]
]
]
], $this->getMappings($model))
]);
} catch (\Exception $exception) {
return $this->error($exception->getMessage());
}
and the update() command within the engine (where the error is occurring) looks like
public function update($models)
{
$models->each(function ($model) {
$params = $this->getRequestBody($model, [
'id' => $model->id,
'body' => $model->toSearchableArray()
]);
$this->client->index($params);
});
}
While I have seen lots of questions online regarding problems with the conflicting mapping error all of the ones that I've seen have had to do with ES6 where one had to specify the mapping type as a field in 'mappings' or were solved using something that I've already tried. Does anyone have an idea as to what could be causing this problem and/or where in my code I should be trying to look to solve this issue? I've run out of ideas.
Thank you all in advance for your help!