在 SQL 中,我可以使用 SQL LIKE 很好地搜索电子邮件地址。
使用电子邮件“stack@domain.com”,搜索“stack”、“@domain.com”、“domain.com”或“domain”可以让我返回所需的电子邮件地址。
如何使用 ElasticSearch 获得相同的结果?
我玩过 nGram、edgeNGram、uax_url_email 等,搜索结果非常糟糕。如果我错了,请纠正我,听起来我必须执行以下操作:
- 对于 index_analyzer
- 使用“keyword”、“whitespace”或“uax_url_email”标记器,这样电子邮件就不会被标记化
- 但通配符查询似乎不起作用(至少有轮胎)
- 使用“nGram”或“edgeNGram”进行过滤
- 在搜索“first-second”时,我总是得到太多不需要的结果,比如得到“first@domain.com”。
- 使用“keyword”、“whitespace”或“uax_url_email”标记器,这样电子邮件就不会被标记化
- 对于 search_analyzer
- 不要做 nGram
一个实验代码
tire.settings :number_of_shards => 1,
:number_of_replicas => 1,
:analysis => {
:filter => {
:db_ngram => {
"type" => "nGram",
"max_gram" => 255,
"min_gram" => 3 }
},
:analyzer => {
:string_analyzer => {
"tokenizer" => "standard",
"filter" => ["standard", "lowercase", "asciifolding", "db_ngram"],
"type" => "custom" },
:index_name_analyzer => {
"tokenizer" => "standard",
"filter" => ["standard", "lowercase", "asciifolding"],
"type" => "custom" },
:search_name_analyzer => {
"tokenizer" => "whitespace",
"filter" => ["lowercase", "db_ngram"],
"type" => "custom" },
:index_email_analyzer => {
"tokenizer" => "whitespace",
"filter" => ["lowercase"],
"type" => "custom" }
}
} do
mapping do
indexes :id, :index => :not_analyzed
indexes :name, :index_analyzer => 'index_name_analyzer', :search_analyzer => 'search_name_analyzer'
indexes :email, :index_analyzer => 'index_email_analyzer', :search_analyzer => 'search_email_analyzer'
end
end
效果不佳的具体情况:
- 带有连字符的电子邮件(例如 email-hyphen@domain.com)
- 开头或结尾的查询字符串'@'
- 完全匹配
- 使用像“ @ ”这样的通配符进行搜索会得到非常意想不到的结果。
假设我有“aaa@email.com”、“aaa_0@email.com”和“aaa-0@email.com”,搜索“aaa”会得到“aaa@a.com”“aaa-0@email。 com。搜索“aaa*”给了我一切,但“aaa-*”什么也没给我。那么,我应该如何进行精确匹配通配符查询呢?对于这些类型的查询,对于不同的标记器/分析器,我得到几乎相同的结果。
我在每次映射更改后执行这些操作: Model.tire.index.delete Model.tire.create_elasticsearch_index Model.tire.index.import Model.all
参考: