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

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

Related

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

Adding a multifield with analyzer in existing field in existing index

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.

How to create a mutlitype index in Elasticsearch?

In several pages in Elasticsearch documentation is mentioned how to query a multi-type index.
But I failed to create one at the first place.
Here is my minimal example (on a Elasticsearch 6.x server):
PUT /myindex
{
"settings" : {
"number_of_shards" : 1
}
}
PUT /myindex/people/123
{
"first name": "John",
"last name": "Doe"
}
PUT /myindex/dog/456
{
"name": "Rex"
}
Index creation and fist insert did well, but at the dog type insert attempt:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Rejecting mapping update to [myindex] as the final mapping would have more than 1 type: [people, dog]"
}
],
"type": "illegal_argument_exception",
"reason": "Rejecting mapping update to [myindex] as the final mapping would have more than 1 type: [people, dog]"
},
"status": 400
}
But this is exactly what I'm trying to do, buddy! Having "more than 1 type" in my index.
Do you know what I have to change in my calls to achieve this?
Many thanks.
Multiple mapping types are not supported from Elastic 6.0.0 onwards. See breaking changes for details.
You can still effectively use multiple types by implementing your own custom type field.
For example:
{
"mappings": {
"doc": {
"properties": {
"type": {
"type": "keyword"
},
"first_name": {
"type": "text"
},
"last_name": {
"type": "text"
}
}
}
}
}
This is described in removal of types.

How to use dot notation in geo percolator

I use Elasticsearch 2.2.1 for searching documents that relate to a specific geo graphic location (within a bouding box). I want to create a percolator that I can use to check if a new document relates to an existing query.
This works fine if I put the percolator into the index containing the documents but because of the issue mention in this document and the workaround mentioned here I need to put the percolate queries into a dedicated percolator index.
When I try to put a percolator into this index:
PUT /mypercindex/.percolator/1
{"query": {"filtered": {"filter":
{"bool":
{"should":
[
{"geo_bounding_box":
{"location.coordinates":
{"bottom_right":
{"lat":50.0,"lon":8.0}
,"top_left":
{"lat":54.0,"lon":3.0}
}
}
}
]
}
}
}}}
I get an error message saying that:
Strict field resolution and no field mapping can be found for the field with name [location.coordinates]
In the percolator documentation is mentioned that, in case of a dedicated percolator index, you need to:
make sure that the mappings from the normal index are also available on the percolate index
This may cause my issue but I cannot find the documentation about how to make the mapping from one index available in the other. I tried to add the dedicated percolator index with the same mapping as my document index but when I do this I still get the same error message.
The mapping of my document index resembles this:
{"my_mapping": {
"dynamic":"strict",
"properties":{
"body":{
"properties":{
"author":{
"type":"string",
"index":"not_analyzed"
},
"hashtags":{
"type":"string",
"index":"not_analyzed"
},
"language":{
"type":"string",
"index":"not_analyzed"
}
,"text":{
"type":"string",
"analyzer":"stopwords"
},
"title":{
"type":"string",
"analyzer":"stopwords"
}
}
},
"location":{
"properties":{
"coordinates":{
"type":"geo_point"
},
"names":{
"type":"string",
"analyzer":"standard"
}
}
}
}
}}
Any help would be greatly appreciated!
Adding a .percolator mapping to the mapping, like mentioned in the Github issue that addresses this workaround, fixed the issue for me:
".percolator": {
"dynamic": true,
"properties": {
"id": {
"type": "integer"
}
}
}

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