How to make a field to have lowercase analyzer after field creation? - elasticsearch

I run
PUT /vehicles/_doc/123
{
"make" : "Honda civic",
"color" : "Blue",
"from": "Japan",
"size": "Big",
"HP" : 250,
"milage" : 24000,
"price": 19300.97
}
at the start
and after that I run
PUT /vehicles
{
"settings": {
"analysis": {
"analyzer": {
"my_lowercase_analyzer": {
"tokenizer": "standard",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"properties": {
"make": {
"type": "text",
"analyzer": "my_lowercase_analyzer"
}
}
}
}
It gives exception
{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [vehicles/o66DtxmERa2lmo2WiiZ65w] already exists",
"index_uuid": "o66DtxmERa2lmo2WiiZ65w",
"index": "vehicles"
}
],
"type": "resource_already_exists_exception",
"reason": "index [vehicles/o66DtxmERa2lmo2WiiZ65w] already exists",
"index_uuid": "o66DtxmERa2lmo2WiiZ65w",
"index": "vehicles"
},
"status": 400
}
Is there away to update analyzer after creation?

Updating the analyzer of an existing field is a breaking change, you can't update it on the same index, you now have below. options
Add another field, on which you can define the new analyzer (of-course this is not recommended as you will loose the old data, but in some cases it may be useful).
Create a new index using same field and updated analyzer definition and after that you can use reindex API to update the data from old to new index.

Related

Getting "resource_already_exists_exception" when trying to update stopwords

I'm using Elasticsearch version 6.8
I have an exsisting index (name q1) and I want to update it's stop words list.
I tried to do it with the following command:
PUT /q1
{
"settings": {
"analysis": {
"filter": {
"my_stop": {
"type": "stop",
"stopwords": ["daa", "dada", "the"]
}
}
}
}
}
But I got errors:
{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [q1/lywbfw9QTaeYVr0dpDnRvw] already exists",
"index_uuid": "lywbfw9QTaeYVr0dpDnRvw",
"index": "q1"
}
],
"type": "resource_already_exists_exception",
"reason": "index [q1/lywbfw9QTaeYVr0dpDnRvw] already exists",
"index_uuid": "lywbfw9QTaeYVr0dpDnRvw",
"index": "q1"
},
"status": 400
}
seems that I can set the stop words (with this command) just for a new index and not for exsisting one.
What is wrong, and how can I update the stop words list of my q1 index ?
Thanks
you need to close your index for updating and open it after.
See more about closing https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-close.html
and opening index https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html
https://hostname:9200/your_index_name/_close
after
PUT /your_index_name/_settings
{
"settings": {
"analysis": {
"filter": {
"my_stop": {
"type": "stop",
"stopwords": ["daa", "dada", "the"]
}
}
}
}
}
then
https://hostname:9200/your_index_name/_open

Set values in multifields elastic search

I have the following structure recorded in elastic:
PUT /movies
{
"mappings": {
"title": {
"properties": {
"title": {
"type": "string",
"fields": {
"de": {
"type": "string",
"analyzer": "german"
},
"en": {
"type": "string",
"analyzer": "english"
},
"fr": {
"type": "string",
"analyzer": "french"
},
"es": {
"type": "string",
"analyzer": "spanish"
}
}
}
}
}
}
}
But when I am trying to record values like this:
PUT movies/_doc/2
{
"title": "fox",
"field": "en"
}
I receive the following error:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Rejecting mapping update to [movies] as the final mapping would have more than 1 type: [_doc, title]"
}
],
"type": "illegal_argument_exception",
"reason": "Rejecting mapping update to [movies] as the final mapping would have more than 1 type: [_doc, title]"
},
"status": 400
}
Maybe I am doing something wrong since I am fairly new to elastic. My idea is to create one to one mapping and when I am searching for Fox in any of these languages to return results only in english since they are recorded in the DB.
Your mapping indicates a mapping type "title" but when you create the documents you use PUT movies/_doc/2 that indicates mapping type _doc which doesn't exist so ES will try to automatically create it, and in newer version of ES having multiple mapping types is forbidden.
You should just change it to: PUT movies/title/2

In Elasticsearch, can I set language-specific multi-fields?

Is it possible to use multi-fields to set and query multilingual fields?
Consider this mapping:
PUT multi_test
{
"mappings": {
"data": {
"_field_names": {
"enabled": false
},
"properties": {
"book_title": {
"type": "text",
"fields": {
"english": {
"type": "text",
"analyzer": "english"
},
"german": {
"type": "text",
"analyzer": "german"
},
"italian": {
"type": "text",
"analyzer": "italian"
}
}
}
}
}
}
}
I tried the following, but it doesn't work:
PUT multi_test/data/1
{
"book_title.english": "It's good",
"book_title.german": "Das gut"
}
The error seems to indicate I'm trying to add new fields:
{ "error": { "root_cause": [ { "type": "mapper_parsing_exception",
"reason": "Could not dynamically add mapping for field
[book_title.english]. Existing mapping for [book_title] must be of
type object but found [text]." } ], "type":
"mapper_parsing_exception", "reason": "Could not dynamically add
mapping for field [book_title.english]. Existing mapping for
[book_title] must be of type object but found [text]." }, "status":
400 }
What am I doing wrong here?
If my approach is unworkable, what is a better way to do this?
The problem is that you are using using fields for the field book_title.
Fields keyword is used when you want to keep same field and data in multiple ways i.e using different analyzers or some other setting changes but values should be same in all field names under fields.Here is the link describing what is keyword fields https://www.elastic.co/guide/en/elasticsearch/reference/2.4/multi-fields.html
In you use case the mapping should be like below
PUT multi_test
{
"mappings": {
"data": {
"_field_names": {
"enabled": false
},
"properties": {
"book_title": {
"properties": {
"english": {
"type": "text",
"analyzer": "english"
},
"german": {
"type": "text",
"analyzer": "german"
},
"italian": {
"type": "text",
"analyzer": "italian"
}
}
}
}
}
}
}
This will define book_title as object type and you can add multiple fields with different data under book_title

Elasticsearch index analyzer settings

I am a beginner for elastic search. I tried to add an analyzer to my index. Here is the coding:
PUT drug_mono6/_settings
{
"analysis": {
"analyzer": {
"attachment.content": {
"type": "custom",
"tokenizer": "Whitespace"
}
}
}
}
However, I was not able to reopen the index after doing that. The error I received is:
{
"error": {
"root_cause": [
{
"type": "exception",
"reason": "Failed to verify index [drug_mono6/SMmaJ4iPTCSUHp-oedsadA]"
}
],
"type": "exception",
"reason": "Failed to verify index [drug_mono6/SMmaJ4iPTCSUHp-oedsadA]",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "analyzer [attachment] must specify either an analyzer type, or
a tokenizer"
}
},
"status": 500
}`
Is there a way to modify the settings and remove the changes?
this should work
PUT drug_mono6
{
"analysis": {
"analyzer": {
"attachment": {
"type": "custom",
"tokenizer": "whitespace"
}
}
}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-custom-analyzer.html

Update and search in multi field properties in ElasticSearch

I'm trying to use multi field properties for multi language support. I created following mapping for this:
{
"mappings": {
"product": {
"properties": {
"prod-id": {
"type": "string"
},
"prod-name": {
"type": "string",
"fields": {
"en": {
"type": "string",
"analyzer": "english"
},
"fr": {
"type": "string",
"analyzer": "french"
}
}
}
}
}
}
}
I created test record:
{
"prod-id": "1234567",
"prod-name": [
"Test product",
"Produit d'essai"
]
}
and tried to query using some language:
{
"query": {
"bool": {
"must": [
{"match": {
"prod-name.en": "Produit"
}}
]
}
}
}
As a result I got my document. But I expected that I will have empty result when I use French but choose English. It seems ElasticSearch ignores which field I specified in query. There is no difference in search result when I use "prod-name.en" or "prod-name.fr" or just "prod-name". Is this behaviour expected? Should I do some special things to have searching just in one language?
Another problem with updating multi field property. I can't update just one field.
{
"doc" : {
"prod-name.en": "Test"
}
}
I got following error:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Field name [prod-name.en] cannot contain '.'"
}
],
"type": "mapper_parsing_exception",
"reason": "Field name [prod-name.en] cannot contain '.'"
},
"status": 400
}
Is there any way to update just one field in multi field property?
In your mapping, the prod-name.en field will simply be analyzed using the english analyzer and the same for the french field. However, ES will not choose for you which value to put in which field.
Instead, you need to modify your mapping like this
{
"mappings": {
"product": {
"properties": {
"prod-id": {
"type": "string"
},
"prod-name": {
"type": "object",
"properties": {
"en": {
"type": "string",
"analyzer": "english"
},
"fr": {
"type": "string",
"analyzer": "french"
}
}
}
}
}
}
}
and input document to be like this and you'll get the results you expect.
{
"prod-id": "1234567",
"prod-name": {
"en": "Test product",
"fr": "Produit d'essai"
}
}
As for the updating part, your partial document should be like this instead.
{
"doc" : {
"prod-name": {
"en": "Test"
}
}
}

Resources