2
votes

Hello For certain requirement i have made all the index not_analyzed

{
"template": "*",
"mappings": {
    "_default_": {
        "dynamic_templates": [
            {
                "my_template": {
                    "match_mapping_type": "string",
                    "mapping": {
                        "index": "not_analyzed"
                    }
                }
            }
        ]
    }
}
   }

But now as per our requirement i have to make certain field as analyzed . and keep rest of the field as not analyzed

My Data is of type :

{   "field1":"Value1",
       "field2":"Value2",
       "field3":"Value3",
"field4":"Value3",
"field5":"Value4",
"field6":"Value5",
"field7":"Value6",
"field8":"",
"field9":"ce-3sdfa773-7sdaf2-989e-5dasdsdf",
"field10":"12345678",
"field11":"ertyu12345ffd",
"field12":"A",
"field13":"Value7",
"field14":"Value8",
"field15":"Value9",
"field16":"Value10",
"field17":"Value11",
"field18":"Value12",
"field19":{
"field20":"Value13",
"field21":"Value14"
},
"field22":"Value15",
"field23":"ipaddr",
"field24":"datwithtime",
"field25":"Value6",
"field26":"0",
"field20":"0",
"field28":"0"
}

If i change my template as per recommendation to something like this

{
   "template": "*",
   "mappings": {
    "_default_": {
      "properties": {
        "filed6": {
          "type": "string",
          "analyzer": "keyword",
          "fields": {
                     "raw": {
                        "type": "string",
                        "index": "not_analyzed"
                     }
                  }}},
      "dynamic_templates": [
        {
          "my_template": {
            "match_mapping_type": "*",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

Then i get error while i insert data stating

{"error":"MapperParsingException[failed to parse [field19]]; nested: ElasticsearchIllegalArgumentException[unknown property [field20 ]]; ","status":400}

2

2 Answers

4
votes

In short you want to change the mapping of your index.

  • If your index does not contain any data(which I suppose, is not the case), then you can simply delete the index and create it again with new mapping.
  • If your index contains data, you will have to reindex it.

Steps for reindexing:

  • Put all data from existing index to dummy index.
  • Delete existing index. Generate new mapping.
  • Transfer data from dummy index to newly created index.

You can also give a look to elastic search alias here

This link might also be useful.

If you want to use the same field as analysed and not analysed at the same time you have to use multifield using

"title": {
"type": "multi_field",
"fields": {
    "title": { "type": "string" },
    "raw":   { "type": "string", "index": "not_analyzed" }
 }
}

This is for your reference.

For defining multifield in dynamic_templates use:

{
"template": "*",
"mappings": {
"_default_": {
    "dynamic_templates": [
        {
            "my_template": {
                "match_mapping_type": "string",
                 "mapping": {
                 "type": "string",
                 "fields": {
                  "raw": {
                   "type":  "string",
                     "index": "not_analyzed"
                }
               }
              }
            }
        }
      ]
    }
  }
 }

Refer this for more info on this.

1
votes

You can either write multiple templates or have separate properties depending on your requirements. Both will work smoothly.

1) Multiple Templates

{
  "mappings": {
    "your_doctype": {
      "dynamic_templates": [
        {
          "analyzed_values": {
            "match_mapping_type": "*",
            "match_pattern": "regex",
            "match": "title|summary",
            "mapping": {
              "type": "string",
              "analyzer": "keyword"
            }
          }
        },
        {
          "date_values": {
            "match_mapping_type": "date",
            "match": "*_date",
            "mapping": {
              "type": "date"
            }
          }
        },
        {
          "exact_values": {
            "match_mapping_type": "*",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

Here title and summary are analyzed by keyword analyzer. I have also added date field which is optional, it will map create_date etc as date. Last one will match anything and it will not_analyzed which will fulfill your requirements.

2) Add analyzed field as properties.

{
  "mappings": {
    "your_doctype": {
      "properties": {
        "title": {
          "type": "string",
          "analyzer": "keyword"
        },
        "summary": {
          "type": "string",
          "analyzer": "keyword"
        }
      },
      "dynamic_templates": [
        {
          "any_values": {
            "match_mapping_type": "*",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

Here title and summary fields are analyzed while rest will be not_analyzed

You would have to reindex the data no matter which solution you take.

EDIT 1 : After looking at your data and mapping, there is one slight problem in it. Your data contains object structure and you are mapping everything apart from filed6 as string and filed19 is an Object and not string and hence ES is throwing the error. The solution is to let ES decide which datatype the field is with dynamic_type. Change your mapping to this

{
  "template": "*",
  "mappings": {
    "_default_": {
      "properties": {
        "filed6": {
          "type": "string",
          "analyzer": "keyword",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      },
      "dynamic_templates": [
        {
          "my_template": {
            "match_mapping_type": "*",
            "mapping": {
              "type": "{dynamic_type}", <--- this will decide if field is either object or string.
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

Hope this helps!!