Una manera fácil de hacer esto es crear un analizador personalizado que utilice el filtro de token n-gram
para correos electrónicos (=> ver a continuación index_email_analyzer
y search_email_analyzer
+ email_url_analyzer
para la coincidencia exacta de correo electrónico) y edge-ngram filtro de fichas
para teléfonos (=> ver a continuación index_phone_analyzer
y search_phone_analyzer
).
La definición completa del índice está disponible a continuación.
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"
}
}
}
}
}
Ahora, vamos a diseccionarlo un poco tras otro.
Para el phone
campo, la idea es indexar los valores del teléfono con index_phone_analyzer
, que utiliza un tokenizador edge-ngram para indexar todos los prefijos del número de teléfono. Entonces, si su número de teléfono es 1362435647
, se producirán los siguientes tokens:1
, 13
, 136
, 1362
, 13624
, 136243
, 1362435
, 13624356
, 13624356
, 136243564
, 1362435647
.
Luego, cuando buscamos, usamos otro analizador search_phone_analyzer
que simplemente tomará el número de entrada (por ejemplo, 136
) y compararlo con el phone
campo usando una simple match
o term
consulta:
POST myindex
{
"query": {
"term":
{ "phone": "136" }
}
}
Para el email
Procedemos de manera similar, en el sentido de que indexamos los valores de correo electrónico con el index_email_analyzer
, que utiliza un filtro de token de ngram, que producirá todos los tokens posibles de longitud variable (entre 1 y 20 caracteres) que se pueden tomar del valor del correo electrónico. Por ejemplo:[email protected]
será tokenizado a j
, jo
, joh
, ..., gmail.com
, ..., [email protected]
.
Luego, al buscar, usaremos otro analizador llamado search_email_analyzer
que tomará la entrada e intentará compararla con los tokens indexados.
POST myindex
{
"query": {
"term":
{ "email": "@gmail.com" }
}
}
El email_url_analyzer
El analizador no se usa en este ejemplo, pero lo he incluido en caso de que necesite hacer coincidir el valor exacto del correo electrónico.