Adding a multifield with analyzer in existing field in existing index - elasticsearch

I have an existing index in elasticsearch (version : 5.1.1) which has some documents index in it.
A mapping in the index (say hardware) has a a field as follows :
"biosSerialNumber" :{
"type":"keyword"
}
I want to add a field to it with analyzer as follows :
"biosSerialNumber" :{
"type":"keyword",
"fields":{
"suffix":{
"type":"text",
"analyzer":"abc_analyzer"
}
}
}
"abc_analyzer" analyzer already exists in the index settings.
Is it allowed? I have tried doing this using PUT commands which I have used to add new fields in the index.
But it does not seem to work.
Getting this error :
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [fields] has unsupported parameters: [analyzer : suffix_match_analyzer]"
}
],
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [fields] has unsupported parameters: [analyzer : suffix_match_analyzer]"
},
"status": 400 }

As mentioned in the comment, the error was because I was trying to add an analyzer to a 'keyword' field, which is not allowed (for the obvious reason that keyword type is not analyzed)!. This was a sample try-out.
Also, now after running a PUT request to :
<elshost>/<index-name>/_mapping/<doc-type>
with the request body :
{
"properties":{
"asset":{
"properties" :{
"biosSerialNumber":{
"type":"keyword",
"fields":{
"suffix":{
"type":"text",
"analyzer":"abc_analyzer"
}
}
}
}
}
}
}
worked.
I understand, for this to take effect on the existing data in the field, documents need to be re-indexed.

Related

How can i fix this error Mapper for [description] conflicts with existing mapper:Cannot update parameter [analyzer] from [my_analyzer] to [default]

am new to elastic search.please help me out with this problem.
Am using elastic search version 7.13.2 .
I created an index with a custom analyzer and filter like this
PUT /analyzers_test
{
"settings": {
"analysis": {
"analyzer": {
"english_stop":{
"type":"standard",
"stopwords":"_english_"
},
"my_analyzer":{
"type":"custom",
"tokenizer":"standard",
"char_filter":["html_strip"
],
"filter":[
"lowercase",
"trim",
"my_stemmer"]
}
},
"filter": {
"my_stemmer":{
"type":"stemmer",
"name":"english"
}
}
}
}
}
Then i created a mapping for the document i will have and specified my custom analyzer i created earlier (there is no document in the index yet)
like so:
PUT /analyzers_test/_mapping
{
"properties": {
"description":{
"type": "text",
"analyzer": "my_analyzer"
},
"teaser":{
"type": "text"
}
}
}
When i try try to create a document like so
POST /analyzers_test/1
{
"description":"drinking",
"teaser":"drinking"
}
i get the following error
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "Mapper for [description] conflicts with existing mapper:\n\tCannot update parameter [analyzer] from [my_analyzer] to [default]"
}
],
"type" : "illegal_argument_exception",
"reason" : "Mapper for [description] conflicts with existing mapper:\n\tCannot update parameter [analyzer] from [my_analyzer] to [default]"
},
"status" : 400
}
Use index API to add document to your index. You are missing the _doc
"You cannot change the mapping (including the analyzer) of an existing field. What you need to do if you want to change the mapping of existing documents is reindex those documents to another index with the updated mapping." Abdon Pijpelink
Click the name for the original discussion

In elasticsearch, what's different between /doc/_mapping and /doc {"mappings"...}

I have confusion about elasticsearch mapping
First, I have a doc created with mapping request as
PUT /person
{
"mappings":{
"properties":{
"firstname":{
"type":"text"
}
}
}
}
Then, I want to add new property "lastname", to do that I PUT
PUT /person
{
"mappings":{
"properties":{
"lastname":{
"type":"text"
}
}
}
}
Unfortunately, the exception stops me
{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [person/5TWopRJaQ3Clam2TiteuHg] already exists",
"index_uuid": "5TWopRJaQ3Clam2TiteuHg",
"index": "person"
}
],
"type": "resource_already_exists_exception",
"reason": "index [person/5TWopRJaQ3Clam2TiteuHg] already exists",
"index_uuid": "5TWopRJaQ3Clam2TiteuHg",
"index": "person"
},
"status": 400
}
It trys to tell me index existed, I could not update it.
But if I use,
PUT /person/_mapping
{
"properties":{
"lastname":{
"type":"text"
}
}
}
it works, and "lastname" is added into mapping.
What's the difference between /person/ {mappings:...} and /person/_mapping {...}?
They are all PUT method, shouldn't they do the same?
Or /person/ {mappings:...} could only be used as created, and /person/_mapping {...} is only for updating existed ones?
Not very make sense. What's the trick here?
https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html
Indices created in Elasticsearch 7.0.0 or later no longer accept a _default_ mapping. Indices created in 6.x will continue to function as before in Elasticsearch 6.x. Types are deprecated in APIs in 7.0, with breaking changes to the index creation, put mapping, get mapping, put template, get template and get field mappings APIs.
Hence, mappings support is deprecated in ES 7 and will be removed in ES 8

Elastic Search: Alternative of flattened datatype in Elastic Search 7.1

I have two Elastic Search version one is 7.3 and the second is 7.1. I am using flattened data type for Elastic Search 7.3 and I also want to use this data type in Elastic Search 7.1. So that I can store my data as I stored in Elastic Search 7.3.
I researched about flattened data type and get to know that it's supported to 7.x but when I tried in 7.1 it gives me the mapper_parsing_exception error.
What I tried is as shown below.
In Elastic Search 7.3
Index Creation
PUT demo-flattened
Response:
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "demo-flattened"
}
Insert Mapping
PUT demo-flattened/_mapping
{
"properties": {
"host": {
"type": "flattened"
}
}
}
Response:
{
"acknowledged": true
}
In Elastic Search 7.1
PUT demo-flattened
Response:
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "demo-flattened"
}
Insert Mapping
PUT demo-flattened/_mapping
{
"properties": {
"host": {
"type": "flattened"
}
}
}
Response:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "No handler for type [flattened] declared on field [host]"
}
],
"type": "mapper_parsing_exception",
"reason": "No handler for type [flattened] declared on field [host]"
},
"status": 400
}
I want to use the flattened data type in Elastic Search 7.1. Is there any alternative to use flattened data type in the 7.1 version because flattened data type is supported from Elastic Search 7.3.
Any help or suggestions will be appreciated.
First the flattened is available in 7.1 with X-pack (X-pack is paid feature),
so what I think you can use object type with enabled flag as false
This will help you store that field as it is without any indexing.
{
"properties": {
"host": {
"type": "object",
"enabled": false
}
}
}
Check the version of your ElasticSearch. If its the OSS version, then it won't work for you.
You can check it by running GET \ in the Kibana. You would get something like:
{
"version" : {
"number" : "7.10.2",
"build_flavor" : "oss",
}
}
But for ElasticSearch that does support flattened type, you would get something like:
"version" : {
"number" : "7.10.2",
"build_flavor" : "default",
}
}
You can find more details on the official Kibana Github page No handler for type [flattened] declared on field [state] #52324.
Interally, it works like this
Similarities in the way values are indexed, flattened fields share much of the same mapping and search functionality as keyword fields
Here, You have only one field called host. You can replace this with keyword.
What similarities:
Mapping:
"labels": {
"type": "flattened"
}
Data:
"labels": {
"priority": "urgent",
"release": ["v1.2.5", "v1.3.0"],
"timestamp": {
"created": 1541458026,
"closed": 1541457010
}
}
During indexing, tokens are created for each leaf value in the JSON object. The values are indexed as string keywords, without analysis or special handling for numbers or dates
To query them, you can use "term": {"labels": "urgent"} or "term": {"labels.release": "v1.3.0"}.
When it is keyword, you can have them as separate fields.
{
"host":{
"type":"keyword"
}
}
Reference

elasticsearch routing on specific field

hi I want to set custom routing on specific field "userId" on my Es v2.0.
But it giving me error.I don't know how to set custom routing on ES v2.0
Please guys help me out.Thanks in advance.Below is error message, while creating custom routing with existing index.
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [_routing] has unsupported parameters: [path : userId]"
}
],
"type": "mapper_parsing_exception",
"reason": "Mapping definition for [_routing] has unsupported parameters: [path : userId]"
},
"status": 400
}
In ES 2.0, the _routing.path meta-field has been removed. So now you need to do it like this instead:
In your mapping, you can only specify that routing is required (but you cannot specify path anymore):
PUT my_index
{
"mappings": {
"my_type": {
"_routing": {
"required": true
},
"properties": {
"name": {
"type": "string"
}
}
}
}
}
And then when you index a document, you can specify the routing value in the query string like this:
PUT my_index/my_type/1?routing=bar
{
"name": "foo"
}
You can still use custom routing based on a field from the data being indexed. You can setup a simple pipeline and then use the pipeline every time you index a document, or you can also change the index settings to use the pipeline whenever the index receives a document indexing request.
Read about the pipeline here
Do read above and below the docs for more clarity. It's not meant for setting custom routing, but can be used for the purpose. Custom routing was disabled for a good reason that the field to be used can turn out to have null values leading to unexpected behavior. Hence take care of that issue by yourself.
For routing, here is a sample pipeline PUT :
PUT localhost:9200/_ingest/pipeline/nameRouting
Content-Type: application/json
{
"description" : "Set's the routing value from name field in document",
"processors" : [
{
"set" : {
"field": "_routing",
"value": "{{_source.name}}"
}
}
]
}
The index settings will be :
{
"settings" : {
"index" : {
"default_pipeline" : "nameRouting"
}
}
}

Overriding default keyword analysis for elasticsearch

I am trying to configure an elasticsearch index to have a default indexing policy of analysis with the keyword analyzer, and then overriding it on some fields, to allow them to be free text analyzed. So effectively opt-in free text analysis, where I am explicitly specifying in the mapping which fields are analysed for free text matching. My mapping defintion looks like this:
PUT test_index
{
"mappings":{
"test_type":{
"index_analyzer":"keyword",
"search_analyzer":"standard",
"properties":{
"standard":{
"type":"string",
"index_analyzer":"standard"
},
"keyword":{
"type":"string"
}
}
}
}
}
So standard should be an analyzed field, and keyword should be exact match only. However when I insert some sample data with the following command:
POST test_index/test_type
{
"standard":"a dog in a rug",
"keyword":"sheepdog"
}
I am not getting any matches against the following query:
GET test_index/test_type/_search?q=dog
However I do get matches against:
GET test_index/test_type/_search?q=*dog*
Which makes me think that the standard field is not being analyzed. Does anyone know what I am doing wrong?
Nothing's wrong with the index created. Change your query to GET test_index/test_type/_search?q=standard:dog and it should return the expected results.
If you do not want to specify field name in the query, update your mapping such that you provide the index_analyzer and search_analyzer values explicitly for each field with no default values. See below:
PUT test_index
{
"mappings": {
"test_type": {
"properties": {
"standard": {
"type": "string",
"index_analyzer": "standard",
"search_analyzer": "standard"
},
"keyword": {
"type": "string",
"index_analyzer": "keyword",
"search_analyzer": "standard"
}
}
}
}
}
Now if you try GET test_index/test_type/_search?q=dog, you'll get the desired results.

Resources