我需要通过电子邮件搜索联系人。根据ES 文档,实现这一目标的最佳方法是使用分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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
和映射:
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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
创建索引后,我插入了两个文档:
curl -X PUT 'localhost:9200/contacts/contact/1' -d '{"contact_status": "confirmed", "email": "example@gmail.com", "id": "1", "user_id": "1", "subscription_status": "on"}'
Run Code Online (Sandbox Code Playgroud)
和
curl -X PUT 'localhost:9200/contacts/contact/2' -d '{"contact_status": "confirmed", "email": "example@yahoo.com", "id": "2", "user_id": "2", "subscription_status": "on"}'
Run Code Online (Sandbox Code Playgroud)
然后我尝试以不同的方式通过电子邮件搜索联系人:
curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "example@google.com", "analyzer": "email" } } } ] } } }'
Run Code Online (Sandbox Code Playgroud)
我希望在 id=1 时得到 1 个结果,但得到了空命中:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
Run Code Online (Sandbox Code Playgroud)
我测试过的下一个搜索查询是:
curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "example@google", "analyzer": "email" } } } ] } } }'
Run Code Online (Sandbox Code Playgroud)
返回 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"
}
} ]
}
}
Run Code Online (Sandbox Code Playgroud)
但如您所知,我希望在搜索结果中获得 1 个文档。我究竟做错了什么?
Bos*_*nne 11
用它来提出你的要求它对我有用
GET my_index/_search
{
"query": {
"match_phrase_prefix" : {
"email": "valery@gmail.com"
}
}
}
Run Code Online (Sandbox Code Playgroud)
你会有期待的结果
这是发生的事情:
" uax_url_email
" 分词器等于“标准”分词器(意思是它删掉了“@”),除非它得到一种模式,"<text>@<text>.<text>"
在这种情况下它不删掉“@”而是将整个电子邮件地址作为一个标记。
现在,在索引时,您将“电子邮件”字段定义为“字符串”,默认为“标准”标记器,这意味着 - 您的地址被标记为2 个标记:“ example
”和“ gmail.com
”!在搜索时您定义了“电子邮件”标记器,这意味着您的(第一个)查询“example@google.com”根本没有被标记(因为它属于电子邮件模式),因此它既不匹配“example”也不匹配“gmail.com”(雅虎也是如此)。在您的第二个查询中,您搜索了“example@google” - 这不属于整个电子邮件模式,因此电子邮件标记器作为“标准”标记器工作,这意味着它会剪切“@”并将“example”和“google”标记化 在您的索引中寻找任何一个。由于示例已在您的 2 个文档中编入索引 - 它适合两者!
如果您只想匹配地址的“示例”部分 - 您不能在搜索时使用“电子邮件”分析器!在任何情况下,大多数情况下,您不应该从索引分析器更改搜索分析器!
请注意,“标准”分析器不会将“gmail.com”切成 2 个标记!
归档时间: |
|
查看次数: |
7552 次 |
最近记录: |