字母数字的 ElasticSearch 分析器自动完成功能
ElasticSearch analyzer auto-complete feature for alphanumeric
我有 Hcc18、HCC23、I23 等字母数字代码,我想将其存储在 ElasticSearch 中。在此基础上,我想构建以下两个功能:-
- 用户可以搜索完整的字母数字代码或仅搜索整数部分。
示例:
对于 hcc15 或 15,hcc15 应该在输出中并位于结果的顶部。
- 自动完成功能:当用户键入 I42 时,结果应包含 I420、I421 等。
我的 Elasticsearch 当前映射是:
"mappings": {
"properties": {
"code": {
"type": "text",
"analyzer": "autoanalyer"
}
}
},
"settings": {
"analysis": {
"analyzer": {
"autoanalyer": {
"tokenizer": "standard",
"filter": [
"lowercase",
]
}
},
"tokenizer": {
"autotoken": {
"type": "simple_pattern",
"pattern": "[0-9]+"
}
}
}
}
正在查询:
{
"min_score": 0.1,
"from": 0,
"size": 10000,
"query": {
"bool": {
"should": [{ "match": {"code": search_term}}]
}
}
}
两个问题,我用这个方法面临的是:-
假设我搜索 I420,现在因为映射仅基于数字,
我得到了与数字 420 相关的所有代码,但确切的
匹配 I420 没有排在首位。
请问这个映射怎么才能实现上面说的
自动完成功能.
您有多个要求,所有这些都可以使用
实现
- 创建一个 custom analyzer 根据我们的要求标记数据。
- 使用 bool 查询结合 the prefix(用于自动完成)和数字搜索匹配。
下面是使用 OP 数据和查询的分步示例。
索引定义
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "autotoken" -->used your analyzer to extract numbers
}
},
"tokenizer": {
"autotoken": {
"type": "simple_pattern",
"pattern": "[0-9]+",
"preserve_original": true
}
}
}
},
"mappings": {
"properties": {
"code": {
"type": "keyword",
"fields": {
"number": {
"type": "text",
"analyzer" : "my_analyzer"
}
}
}
}
}
}
索引几个文档
{
"code" : "hcc420"
}
{
"code" : "HCC23"
}
{
"code" : "I23"
}
{
"code" : "I420"
}
{
"code" : "I421"
}
{
"code" : "hcc420"
}
搜索查询(问题 1,搜索 I420
,应该在样本数据 I420
和 hcc420
中带 2 个文档,但 I420
必须有更多的分数作为完全匹配)
{
"query": {
"bool": {
"should": [
{
"prefix": {
"code": {
"value": "I420"
}
}
},
{
"match": {
"code.number": "I420"
}
}
]
}
}
}
结果
"hits": [
{
"_index": "so_number",
"_type": "_doc",
"_id": "4",
"_score": 2.0296195, --> note exact match having high score
"_source": {
"code": "I420"
}
},
{
"_index": "so_number",
"_type": "_doc",
"_id": "7",
"_score": 1.0296195,
"_source": {
"code": "hcc420"
}
}
]
第 2 部分:相同的搜索查询可以使用自动完成功能
所以搜索 I42
必须从示例文档 I420
和 I421
{
"query": {
"bool": {
"should": [
{
"prefix": {
"code": {
"value": "I42"
}
}
},
{
"match": {
"code.number": "I42"
}
}
]
}
}
}
结果
"hits": [
{
"_index": "so_number",
"_type": "_doc",
"_id": "4",
"_score": 1.0,
"_source": {
"code": "I420"
}
},
{
"_index": "so_number",
"_type": "_doc",
"_id": "5",
"_score": 1.0,
"_source": {
"code": "I421"
}
}
]
再举个例子,查号,查420
一定要带hcc420
和I420
搜索查询
{
"query": {
"bool": {
"should": [
{
"prefix": {
"code": {
"value": "420"
}
}
},
{
"match": {
"code.number": "420"
}
}
]
}
}
}
And whoa, again it gave expected results
Result
------
"hits": [
{
"_index": "so_number",
"_type": "_doc",
"_id": "4",
"_score": 1.0296195,
"_source": {
"code": "I420"
}
},
{
"_index": "so_number",
"_type": "_doc",
"_id": "7",
"_score": 1.0296195,
"_source": {
"code": "hcc420"
}
}
]
我有 Hcc18、HCC23、I23 等字母数字代码,我想将其存储在 ElasticSearch 中。在此基础上,我想构建以下两个功能:-
- 用户可以搜索完整的字母数字代码或仅搜索整数部分。
示例: 对于 hcc15 或 15,hcc15 应该在输出中并位于结果的顶部。 - 自动完成功能:当用户键入 I42 时,结果应包含 I420、I421 等。
我的 Elasticsearch 当前映射是:
"mappings": {
"properties": {
"code": {
"type": "text",
"analyzer": "autoanalyer"
}
}
},
"settings": {
"analysis": {
"analyzer": {
"autoanalyer": {
"tokenizer": "standard",
"filter": [
"lowercase",
]
}
},
"tokenizer": {
"autotoken": {
"type": "simple_pattern",
"pattern": "[0-9]+"
}
}
}
}
正在查询:
{
"min_score": 0.1,
"from": 0,
"size": 10000,
"query": {
"bool": {
"should": [{ "match": {"code": search_term}}]
}
}
}
两个问题,我用这个方法面临的是:-
假设我搜索 I420,现在因为映射仅基于数字, 我得到了与数字 420 相关的所有代码,但确切的 匹配 I420 没有排在首位。
请问这个映射怎么才能实现上面说的 自动完成功能.
您有多个要求,所有这些都可以使用
实现- 创建一个 custom analyzer 根据我们的要求标记数据。
- 使用 bool 查询结合 the prefix(用于自动完成)和数字搜索匹配。
下面是使用 OP 数据和查询的分步示例。
索引定义
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "autotoken" -->used your analyzer to extract numbers
}
},
"tokenizer": {
"autotoken": {
"type": "simple_pattern",
"pattern": "[0-9]+",
"preserve_original": true
}
}
}
},
"mappings": {
"properties": {
"code": {
"type": "keyword",
"fields": {
"number": {
"type": "text",
"analyzer" : "my_analyzer"
}
}
}
}
}
}
索引几个文档
{
"code" : "hcc420"
}
{
"code" : "HCC23"
}
{
"code" : "I23"
}
{
"code" : "I420"
}
{
"code" : "I421"
}
{
"code" : "hcc420"
}
搜索查询(问题 1,搜索 I420
,应该在样本数据 I420
和 hcc420
中带 2 个文档,但 I420
必须有更多的分数作为完全匹配)
{
"query": {
"bool": {
"should": [
{
"prefix": {
"code": {
"value": "I420"
}
}
},
{
"match": {
"code.number": "I420"
}
}
]
}
}
}
结果
"hits": [
{
"_index": "so_number",
"_type": "_doc",
"_id": "4",
"_score": 2.0296195, --> note exact match having high score
"_source": {
"code": "I420"
}
},
{
"_index": "so_number",
"_type": "_doc",
"_id": "7",
"_score": 1.0296195,
"_source": {
"code": "hcc420"
}
}
]
第 2 部分:相同的搜索查询可以使用自动完成功能
所以搜索 I42
必须从示例文档 I420
和 I421
{
"query": {
"bool": {
"should": [
{
"prefix": {
"code": {
"value": "I42"
}
}
},
{
"match": {
"code.number": "I42"
}
}
]
}
}
}
结果
"hits": [
{
"_index": "so_number",
"_type": "_doc",
"_id": "4",
"_score": 1.0,
"_source": {
"code": "I420"
}
},
{
"_index": "so_number",
"_type": "_doc",
"_id": "5",
"_score": 1.0,
"_source": {
"code": "I421"
}
}
]
再举个例子,查号,查420
一定要带hcc420
和I420
搜索查询
{
"query": {
"bool": {
"should": [
{
"prefix": {
"code": {
"value": "420"
}
}
},
{
"match": {
"code.number": "420"
}
}
]
}
}
}
And whoa, again it gave expected results
Result
------
"hits": [
{
"_index": "so_number",
"_type": "_doc",
"_id": "4",
"_score": 1.0296195,
"_source": {
"code": "I420"
}
},
{
"_index": "so_number",
"_type": "_doc",
"_id": "7",
"_score": 1.0296195,
"_source": {
"code": "hcc420"
}
}
]