Warm tip: This article is reproduced from stackoverflow.com, please click
elasticsearch

Elasticsearch keys with names that are substrings of one another

发布于 2020-03-27 10:16:38

I've been playing with Elasticsearch for about a day now, so I'm extremely new. I am trying to POST/import a simple document:

{
    "compression" : "none",
    "compression.level" : "0"
}

I get the following error:

{
"error": {
"root_cause": [
  {
"type": "mapper_parsing_exception",
"reason": "object mapping for [compression] tried to parse field [compression] as object, but found a concrete value"
}
],
"type": "mapper_parsing_exception",
"reason": "object mapping for [compression] tried to parse field [compression] as object, but found a concrete value"
},
"status": 400
}

From what I understand, Elasticsearch will first see "compression" : "none" and create a key named compression of type string? Then when it sees "compression.level" : "0", it sees that as key "compression" with.. an object value of .level" : "0"? Or...I don't really know.

How could I get this to work as expected? Or why doesn't it work as I'm expecting?

Thank you!

Questioner
Addy
Viewed
96
Opster Elasticsearch Ninja 2019-07-03 21:28

compression is of type object and you are trying to pass a string value, which you can't directly pass. And below error message explains it properly.

object mapping for [compression] tried to parse field [compression] as object, but found a concrete value

An object type can have multiple sub-fields, which are denoted by . and you can pass the individual value to those subfields. So in your case, you can pass the value of compression.level.

Please refer official ES doc for more explanation and examples. https://www.elastic.co/guide/en/elasticsearch/reference/current/object.html

Looks like you are using the dynamic mapping, in this case when elasticsearch sees the field name with ., then if there is a corresponding field with the same name but without ., then it automatically converts it to object type, which is happening in your case.

Let me know what is your requirement if you want a key for your value none, then you should create a document like :

{
    "compression.stategy" : "none", // notice its a another sub-field. 
    "compression.level" : "0"
}

And you can check all the sub-fields by hitting the _mapping https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-mapping.html

Coming to your understanding(if you are using dynamic mapping), it's bit different, ES will first see "compression" : "none" then try to map it to text field, but then it sees another field compression.level and as it uses . in field name, and compression is already present, hence start treating compression as an object type.