Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment rechercher une correspondance floue par e-mail ou par téléphone avec Elasticsearch ?

Un moyen simple de le faire est de créer un analyseur personnalisé qui utilise le filtre de jeton n-gramme pour les emails (=> voir ci-dessous index_email_analyzer et search_email_analyzer + email_url_analyzer pour une correspondance exacte des e-mails) et edge-ngram filtre de jeton pour les téléphones (=> voir ci-dessous index_phone_analyzer et search_phone_analyzer ).

La définition complète de l'index est disponible ci-dessous.

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"
        }
      }
    }
  }
}

Maintenant, disséquons-le un peu après l'autre.

Pour le phone champ, l'idée est d'indexer les valeurs du téléphone avec index_phone_analyzer , qui utilise un tokenizer edge-ngram afin d'indexer tous les préfixes du numéro de téléphone. Donc, si votre numéro de téléphone est 1362435647 , les jetons suivants seront produits :1 , 13 , 136 , 1362 , 13624 , 136243 , 1362435 , 13624356 , 13624356 , 136243564 , 1362435647 .

Ensuite, lors de la recherche, nous utilisons un autre analyseur search_phone_analyzer qui prendra simplement le numéro d'entrée (par exemple 136 ) et faites-le correspondre au phone champ à l'aide d'un simple match ou term requête :

POST myindex
{ 
    "query": {
        "term": 
            { "phone": "136" }
    }
}

Pour le email champ, nous procédons de manière similaire, en ce sens que nous indexons les valeurs d'email avec le index_email_analyzer , qui utilise un filtre de jeton ngram, qui produira tous les jetons possibles de longueur variable (entre 1 et 20 caractères) pouvant être extraits de la valeur email. Par exemple :[email protected] sera tokenisé en j , jo , joh , ..., gmail.com , ..., [email protected] .

Ensuite, lors de la recherche, nous utiliserons un autre analyseur appelé search_email_analyzer qui prendra l'entrée et essaiera de la faire correspondre aux jetons indexés.

POST myindex
{ 
    "query": {
        "term": 
            { "email": "@gmail.com" }
    }
}

L'email_url_analyzer analyseur n'est pas utilisé dans cet exemple mais je l'ai inclus juste au cas où vous auriez besoin de faire correspondre la valeur exacte de l'e-mail.