为什么在 Elasticsearch 中使用"文本"类型时无法搜索电子邮件域名



我在文档中有一个email字段保存在Elasticsearch索引中。我能够搜索@之前的值,但我无法通过搜索域值找到任何东西。

例如,下面的查询give me nothing:

GET transaction-green/_search
{
"query": {
"match": {
"email": "gmail"
}
},
"_source": {
"includes": [
"email"
]
}
}

但它返回文档,如果我搜索test@gmail.comtest

这个email字段的映射是默认的text类型:

"email" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}

为什么域名在搜索时被忽略?

这是由于standrad分析器发生的。当您使用默认分析器时,它将像下面这样分析您的值:

你可以使用下面的API来检查分析器:

POST email/_analyze
{
"analyzer": "standard", 
"text": ["test@gmail.com"]
}
{
"tokens" : [
{
"token" : "test",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "gmail.com",
"start_offset" : 5,
"end_offset" : 14,
"type" : "<ALPHANUM>",
"position" : 1
}
]
}

你可以像下面这样用字符过滤器定义你的自定义分析器,你的查询将会工作:

PUT /email
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": "\.",
"replacement": " "
}
}
}
},
"mappings": {
"properties": {
"email":{
"type": "text",
"analyzer": "my_analyzer"
}
}
}
}

现在您可以使用下面的分析器分析值,您可以看到它将为电子邮件创建3个单独的令牌。

POST email/_analyze
{
"analyzer": "my_analyzer", 
"text": ["test@gmail.com"]
}
{
"tokens" : [
{
"token" : "test",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "gmail",
"start_offset" : 5,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "com",
"start_offset" : 11,
"end_offset" : 14,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}

最新更新