Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Elasticsearch HashMap[String, String] mapping value cannot be not_analyzed

Actually my question is very simple: I want my hashmap value not_analyzed!

Now i have one object contains a hashmap[string, string], looks like:

class SomeObject{
    String id;
    @Field(type=FieldType.Object, index=FieldIndex.not_analyzed)
    Map<String, String> parameters;
}

then Spring data elasticsearch generate the mapping like this at the beggining:

{
    "id": {
      "type": "string"
    },
    "parameters": {
      "type": "object"
    }
}

then after i add some objects to the es, it add more attributes like this:

{
    "id": {
      "type": "string"
    },
    "parameters": {
        "properties": {
             "shiduan": {
                "type": "string"
             },
             "季节": {
                "type": "string"
             }
        }
    }
}

now, because of the parameters's value is analyzed, so cannot be search by es, i mean cannot search chinese value, i have tried i can search english at this time.

THEN, AFTER READ THIS POST https://stackoverflow.com/a/32044370/4148034, I UPDATE THE MAPPING MANUALLY TO THIS:

{
    "id": {
      "type": "string"
    },
    "parameters": {
        "properties": {
             "shiduan": {
                "type": "string",
                "index": "not_analyzed"
             },
             "季节": {
                "type": "string",
                "index": "not_analyzed"
             }
        }
    }
}

I CAN SEARCH CHINESE NOW, SO I KNOW THE PROBLEM IS "not_analyzed", LIKE THE POST SAID.

Finally, anyone can tell me how to make the map value "not_analyzed", i had google and stackoverflow many many times still cannot find the answer, let me know if someone can help, thanks very much.

like image 724
Song Watson Avatar asked Mar 12 '23 18:03

Song Watson


1 Answers

One way to achieve this is to create a mappings.json file on your build path (e.g. yourproject/src/main/resources/mappings) and then reference that mapping using the @Mapping annotation in your class.

@Document(indexName = "your_index", type = "your_type")
@Mapping(mappingPath = "/mappings/mappings.json")
public class SomeObject{
    String id;
    @Field(type=FieldType.Object, index=FieldIndex.not_analyzed)
    Map<String, String> parameters;
}

In that mapping file, we're going to add a dynamic template which will target the subfields of your parameters hashmap and declare them to be not_analyzed string.

{
  "mappings": {
    "your_type": {
      "dynamic_templates": [
        {
          "strings": {
            "match_mapping_type": "string",
            "path_match": "parameters.*",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

You need to make sure to delete your_index first and then restart your application so it can be recreated with the proper mapping.

like image 55
Val Avatar answered Apr 26 '23 12:04

Val