How to index email address and then find

Viewed 134

I tried to create mapping for email address but without no success.

What I want to do is to insert into ElasticSearch email addresses and then make a search on it. For eample. I have inserted this emails:

abc1@abc.net
Abc1@abc.NET
abc2@abc.net
abC2@ABC.net
abc3@abc.net
abc4@abc.net

and when I make a search with:

http://localhost:9200/emails/_search?q=email:abc1@abc.net

I want to get only two document with this specific emails:

abc1@abc.net
Abc1@abc.NET

How should I do this ?

1 Answers

You can define a custom normalizer with a lowercase filter, lowercase filter will ensure that all the letters are changed to lowercase before indexing the document and searching.

Index Mapping:

{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "email": {
        "type": "keyword",
        "normalizer": "my_normalizer"
      }
    }
  }
}

Search Query:

{
  "query": {
    "match": {
      "email": "Abc1@abc.NET"
    }
  }
}

Search Result:

"hits": [
      {
        "_index": "66170150",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.4700036,
        "_source": {
          "email": "abc1@abc.net"
        }
      },
      {
        "_index": "66170150",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.4700036,
        "_source": {
          "email": "Abc1@abc.NET"
        }
      }
    ]

You can also use multi-fields if you have to use the uax_url_email tokenizer

{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "filter": [
            "lowercase"
          ]
        }
      },
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "uax_url_email"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "email": {
        "type": "text",
        "analyzer": "my_analyzer",
        "fields": {
          "raw": {
            "type": "keyword",
            "normalizer": "my_normalizer"
          }
        }
      }
    }
  }
}

Search Query in this case will be

{
  "query": {
    "match": {
      "email.raw": "Abc1@abc.NET"
    }
  }
}

Update 1:

You can also use the lowercase filter, to achieve your use case

{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer",
          "filter":"lowercase"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "uax_url_email"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "email": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}
Related