Question

I'm trying to define dynamic templates in Elastic Search to automatically set analysers for currently undefined properties for translations.

E.g. The following does exactly what i want, which is to set lang.en.title to use the english analyzer:

PUT /cl 
{
    "mappings" : {
        "titles" : {
            "properties" : {
                "id" : {
                    "type" : "integer",
                    "index" : "not_analyzed"
                },
                "lang" : {
                    "type" : "object",
                    "properties" : {
                        "en" : {
                            "type" : "object",
                            "properties" : {
                                "title" : {
                                        "type" : "string",
                                        "index" : "analyzed",
                                        "analyzer" : "english"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Which stems lang.en.title as expected e.g.

GET /cl/_analyze?field=lang.en.title&text=knocked

{
   "tokens": [
      {
         "token": "knock",
         "start_offset": 0,
         "end_offset": 7,
         "type": "<ALPHANUM>",
         "position": 1
      }
   ]
}

But what i'm trying to do is set all future string properties of lang.en to use the english analyser using a dynamic template which i can't seem to get working...

PUT /cl 
{
    "mappings" : {
        "titles" : {
            "dynamic_templates" : [{
                "lang_en" : {
                    "path_match" : "lang.en.*",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed",
                        "analyzer" : "english"
                    }
                }
            }],`enter code here`
            "properties" : {
                "id" : {
                    "type" : "integer",
                    "index" : "not_analyzed"
                },
                "lang" : {
                    "type" : "object"
                }
            }
        }
    }
}

The english analyser isn't being applied as lang.en.title isn't stemmed as desired -

GET /cl/_analyze?field=lang.en.title&text=knocked

{
   "tokens": [
      {
         "token": "knocked",
         "start_offset": 0,
         "end_offset": 7,
         "type": "<ALPHANUM>",
         "position": 1
      }
   ]
}

What am i missing? :)

Was it helpful?

Solution

Your dynamic template is defined correctly. The issue is that you will need to index a document with the lang.en.title field in it before the dynamic template will apply the appropriate mapping. I ran the same dynamic mapping that you have defined above in your question locally and got the same result as you.

However, then I added a single document to the index.

POST /cl/titles/1
{
    "lang.en.title": "Knocked out"
}

After adding the document, I ran the analyzer again and I got the expected output:

GET /cl/_analyze?field=lang.en.title&text=knocked

{
   "tokens": [
      {
         "token": "knock",
         "start_offset": 0,
         "end_offset": 7,
         "type": "<ALPHANUM>",
         "position": 1
      }
   ]
}

The index needs to have a document inserted so that it can execute the defined mapping template for the inserted fields. Once that field exists in the index and has the dynamic mapping applied, _analyze API calls will execute as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top