Мне нужно найти контакты по электронной почте. Согласно ES documentation, лучший способ достичь этого - использовать токенизатор uax_url_email
. Вот мои настройки индекса:ElasticSearch поиск по электронной почте по полному совпадению
settings: {
index: {
creation_date: "1467895098804",
analysis: {
analyzer: {
email: {
type: "custom",
tokenizer: "uax_url_email"
}
}
},
number_of_shards: "5",
number_of_replicas: "1",
uuid: "wL0P6OIaQqqYpFDvIHArTw",
version: {
created: "2030399"
}
}
}
и отображение:
contact: {
dynamic: "false",
properties: {
contact_status: {
type: "string"
},
created_at: {
type: "date",
format: "strict_date_optional_time||epoch_millis"
},
email: {
type: "string"
},
id: {
type: "long"
},
mailing_ids: {
type: "long"
},
subscription_status: {
type: "string"
},
type_ids: {
type: "long"
},
updated_at: {
type: "date",
format: "strict_date_optional_time||epoch_millis"
},
user_id: {
type: "long"
}
}
}
После создания индекса я вставил два документа:
curl -X PUT 'localhost:9200/contacts/contact/1' -d '{"contact_status": "confirmed", "email": "[email protected]", "id": "1", "user_id": "1", "subscription_status": "on"}'
и
curl -X PUT 'localhost:9200/contacts/contact/2' -d '{"contact_status": "confirmed", "email": "[email protected]", "id": "2", "user_id": "2", "subscription_status": "on"}'
Тогда я пытаюсь найти контакты по электронной почте по-разному:
curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "[email protected]", "analyzer": "email" } } } ] } } }'
я ожидал, чтобы получить 1 результат с идентификатором = 1, но получили пустые хиты:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
Следующий поисковый запрос я тестировал был:
curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "[email protected]", "analyzer": "email" } } } ] } } }'
, который вернул 2 результата:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.016878016,
"hits" : [ {
"_index" : "contacts",
"_type" : "contact",
"_id" : "2",
"_score" : 0.016878016,
"_source" : {
"contact_status" : "confirmed",
"email" : "[email protected]",
"id" : "2",
"user_id" : "2",
"subscription_status" : "on"
}
}, {
"_index" : "contacts",
"_type" : "contact",
"_id" : "1",
"_score" : 0.016878016,
"_source" : {
"contact_status" : "confirmed",
"email" : "[email protected]",
"id" : "1",
"user_id" : "1",
"subscription_status" : "on"
}
} ]
}
}
Но, как вы понимаете, я ожидал получить 1 документ в результатах поиска. Что я делаю не так?
Если 'email' содержит только адрес электронной почты, почему бы вам не сделать это поле' 'index": "not_analyzed" ', а затем использовать фильтр' term' для поиска адреса электронной почты? –
Потому что мне также нужно искать по user_id, id и другим полям. Более того, я хочу выполнить поиск по электронной почте, например: введите 'example' на вкладке и получите список писем, содержащих« пример », в моем случае - оба документа. Или, если я набираю 'gmail.com' => получить документ с идентификатором 1 – Hroft
Я предлагаю такой подход: http://stackoverflow.com/questions/30115867/elasticsearch-analyzer-and-tokenizer-for-emails Если у вас есть какие-либо трудности или другой вариант использования, чем тот, который дал мне знать. –