我需要通过电子邮件搜索联系人。根据{{3}},实现这一目标的最佳方法是使用uax_url_email
标记生成器。这是我的索引设置:
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": "example@gmail.com", "id": "1", "user_id": "1", "subscription_status": "on"}'
和
curl -X PUT 'localhost:9200/contacts/contact/2' -d '{"contact_status": "confirmed", "email": "example@yahoo.com", "id": "2", "user_id": "2", "subscription_status": "on"}'
然后我尝试通过电子邮件以不同方式搜索联系人:
curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "example@google.com", "analyzer": "email" } } } ] } } }'
我希望得到1个id = 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": "example@google", "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" : "example@yahoo.com",
"id" : "2",
"user_id" : "2",
"subscription_status" : "on"
}
}, {
"_index" : "contacts",
"_type" : "contact",
"_id" : "1",
"_score" : 0.016878016,
"_source" : {
"contact_status" : "confirmed",
"email" : "example@gmail.com",
"id" : "1",
"user_id" : "1",
"subscription_status" : "on"
}
} ]
}
}
但是据您所知,我希望在搜索结果中获得1个文档。我做错了什么?
答案 0 :(得分:2)
这就是发生的事情:
" uax_url_email
&#34; tokenizer等于&#39;标准&#34; tokenizer(意思是它会删除&#34; @&#34;)除非它得到"<text>@<text>.<text>"
的模式,在这种情况下它不会删除&#34; @&#34;但将整个电子邮件地址作为一个标记。
现在,在索引时间,您已定义&#34;电子邮件&#34; field as&#34; string&#34;默认为&#34;标准&#34; tokenizer,意思是 - 您的地址被标记为 2 令牌:&#34; example
&#34;和&#34; gmail.com
&#34;!在搜索时间,您定义了&#34;电子邮件&#34; tokenizer,意思是你的(第一个)查询&#34; example@google.com"根本没有被标记化(因为它变成了一个电子邮件模式)因此它既不匹配&#34;例如&#34;或&#34; gmail.com&#34; (和雅虎一样)。
在您的第二个查询中,您搜索了&#34;示例@ google&#34; - 这并不属于整个电子邮件模式,因此电子邮件令牌化程序可以作为&#34;标准&#34; tokenizer意味着它会削减&#34; @&#34;和标记化&#34;示例&#34;和#34; google&#34;在你的索引中寻找任何一个。由于示例已在您的2个文档中编入索引 - 它适合两者!
如果您希望只能匹配&#34;示例&#34;您的部分地址 - 您无法使用&#34;电子邮件&#34;分析仪在搜索时! 无论如何,大多数情况下,您不应该从索引分析器 更改搜索分析器!
请注意&#34;标准&#34;分析仪不会削减&#34; gmail.com&#34;分为2个令牌!
答案 1 :(得分:0)
使用它来发出您的请求?对我有用
GET my_index/_search
{
"query": {
"match_phrase_prefix" : {
"email": "valery@gmail.com"
}
}
}
您将获得预期的结果