Home > Mobile >  Place an Analyzer on a a specific array item in a nested object
Place an Analyzer on a a specific array item in a nested object

Time:01-16

I have the following mapping

"mappings":{
   "properties":{
     "name": {
         "type": "text"
       },
     "age": {
        "type": "integer" 
      },
     "customProps":{
       "type" : "nested",
       "properties": {
         "key":{
           "type": "keyword"
         },
         "value": {
           "type" : "keyword"
         }
        }
       }
      } 
     } 

example data

{
  "name" : "person1",
  "age" : 10,
  "customProps":[
   {"hairColor":"blue"},
   {"height":"120"}
  ]
},
{
  "name" : "person2",
  "age" : 30,
  "customProps":[
    {"jobTitle" : "software engineer"},
    {"salaryAccount" : "AvGhj90AAb"}
  ]
}

so i want to be able to search for document by salary account case insensitive, i am also searching using wild card example query is

{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "customProps",
              "query": {
                "bool": {
                 "must": [
                   { "match": { "customProps.key": "salaryAccount" } },
                   { "wildcard": { "customProps.value": "*AvG*"
                   }
                 }
               ]}}}}]}}}

i tried adding analyzer with PUT using the following syntax

{
  "settings":{
    "index":{
      "analysis":{
        "analyzer":{
          "analyzer_case_insensitive" : {
            "tokenizer":"keyword",
            "filter":"lowercase"
          }
        }
      }
    }
  },
  "mappings":{
    "people":{
      "properties":{
        "customProps":{
          "properties":{
            "value":{
              "type": "keyword",
              "analyzer": "analyzer_case_insensitive"
            }
          }
        }
      }
    }
  }
}

im getting the following error

"type" : "mapper_parsing_exception", "reason" : "Root mapping definition has unsupported parameters: [people: {properties={customProps={properties={value={analyzer=analyzer_case_insensitive, type=keyword}}}}}]"

any idea how to do the analyzer for the salary account object in the array when it exists?

CodePudding user response:

Your use case is quite clear, that you want to search on the value of salaryAccount only when this key exists in customProps array.

There are some issues with your mapping definition :

  1. You cannot define a custom analyzer for keyword type field, instead you can use a normalizer
  2. Based on the mapping definition you added at the beginning of the question, it seems that you are using elasticsearch version 7.x. But the second mapping definition that you provided, in that you have added mapping type also (i.e people), which is deprecated in 7.x
  3. There is no need to add the key and value fields in the index mapping.

Adding a working example with index mapping, search query, and search result

Index Mapping:

PUT myidx
{
  "mappings": {
    "properties": {
      "customProps": {
        "type": "nested"
      }
    }
  }
}

Search Query:

You need to use exists query, to check whether a field exists or not. And case_insensitive param in Wildcard query is available since elasticsearch version 7.10. If you are using a version below this, then you need to use a normalizer, to achieve case insensitive scenarios.

POST myidx/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "customProps",
            "query": {
              "bool": {
                "must": [
                  {
                    "exists": {
                      "field": "customProps.salaryAccount"
                    }
                  },
                  {
                    "wildcard": {
                      "customProps.salaryAccount.keyword": {
                        "value": "*aVg*",
                        "case_insensitive": true
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

Search Result:

"hits" : [
      {
        "_index" : "myidx",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 2.0,
        "_source" : {
          "name" : "person2",
          "age" : 30,
          "customProps" : [
            {
              "jobTitle" : "software engineer"
            },
            {
              "salaryAccount" : "AvGhj90AAb"
            }
          ]
        }
      }
    ]
  •  Tags:  
  • Related