Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como combinar fuzzy email ou telefone pelo Elasticsearch?


Uma maneira fácil de fazer isso é criar um analisador personalizado que use o filtro de token n-gram para e-mails (=> veja abaixo index_email_analyzer e search_email_analyzer + email_url_analyzer para correspondência exata de e-mail) e edge-ngram filtro de token para telefones (=> veja abaixo index_phone_analyzer e search_phone_analyzer ).

A definição completa do índice está disponível abaixo.
PUT myindex
{
  "settings": {
    "analysis": {
      "analyzer": {
        "email_url_analyzer": {
          "type": "custom",
          "tokenizer": "uax_url_email",
          "filter": [ "trim" ]
        },
        "index_phone_analyzer": {
          "type": "custom",
          "char_filter": [ "digit_only" ],
          "tokenizer": "digit_edge_ngram_tokenizer",
          "filter": [ "trim" ]
        },
        "search_phone_analyzer": {
          "type": "custom",
          "char_filter": [ "digit_only" ],
          "tokenizer": "keyword",
          "filter": [ "trim" ]
        },
        "index_email_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [ "lowercase", "name_ngram_filter", "trim" ]
        },
        "search_email_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [ "lowercase", "trim" ]
        }
      },
      "char_filter": {
        "digit_only": {
          "type": "pattern_replace",
          "pattern": "\\D+",
          "replacement": ""
        }
      },
      "tokenizer": {
        "digit_edge_ngram_tokenizer": {
          "type": "edgeNGram",
          "min_gram": "1",
          "max_gram": "15",
          "token_chars": [ "digit" ]
        }
      },
      "filter": {
        "name_ngram_filter": {
          "type": "ngram",
          "min_gram": "1",
          "max_gram": "20"
        }
      }
    }
  },
  "mappings": {
    "your_type": {
      "properties": {
        "email": {
          "type": "string",
          "analyzer": "index_email_analyzer",
          "search_analyzer": "search_email_analyzer"
        },
        "phone": {
          "type": "string",
          "analyzer": "index_phone_analyzer",
          "search_analyzer": "search_phone_analyzer"
        }
      }
    }
  }
}

Agora, vamos dissecá-lo um pouco após o outro.

Para o phone campo, a ideia é indexar valores de telefone com index_phone_analyzer , que usa um tokenizer edge-ngram para indexar todos os prefixos do número de telefone. Portanto, se seu número de telefone for 1362435647 , os seguintes tokens serão produzidos:1 , 13 , 136 , 1362 , 13624 , 136243 , 1362435 , 13624356 , 13624356 , 136243564 , 1362435647 .

Então, ao pesquisar, usamos outro analisador search_phone_analyzer que simplesmente levará o número de entrada (por exemplo, 136 ) e combine-o com o phone campo usando um simples match ou term inquerir:
POST myindex
{ 
    "query": {
        "term": 
            { "phone": "136" }
    }
}

Para o email campo, procedemos de maneira semelhante, pois indexamos os valores de email com o index_email_analyzer , que usa um filtro de token ngram, que produzirá todos os tokens possíveis de comprimento variável (entre 1 e 20 caracteres) que podem ser retirados do valor do email. Por exemplo:[email protected] será tokenizado para j , jo , joh , ..., gmail.com , ..., [email protected] .

Então, ao pesquisar, usaremos outro analisador chamado search_email_analyzer que receberá a entrada e tentará combiná-la com os tokens indexados.
POST myindex
{ 
    "query": {
        "term": 
            { "email": "@gmail.com" }
    }
}

O email_url_analyzer analisador não é usado neste exemplo, mas incluí-o apenas no caso de você precisar corresponder ao valor exato do e-mail.