ElasticSearch入门之对单个字段使用多个分词器

本文将会介绍如何在ElasticSearch中对单个字段使用分词器。

ElasticSearch中,如果需要对单个字段使用全文搜索功能,那么,需要将该字段数据类型设置为text,并配置对应的分词器(Analyzer)。

一般,对于英文字段的全文搜索,可使用Standard Analyzer;而对于中文字段的全文搜索,可使用ik分析器。那么,如果需要对单个字段同时使用多个分词器,比如同时使用英语的Standard Analyzer和中文的ik分析器,该如何实现呢?

本文将会具体介绍。

本文所使用的ElasticSearch版本为8.13.0。

mapping

我们假设以下的使用场景,对于一个新闻报道,其文章可能为中文或英语,我们需要对文章内容进行搜索。

我们使用的索引(index)名称为news,共三个字段:新闻标题(title),内容(content)和来源(source_type),其中新闻标题和来源数据类型为keyword,内容字段的数据类型为text,并同时使用英语的Standard Analyzer和中文的ik分析器。

具体的结构(mapping)设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
PUT news
{
"mappings": {
"properties": {
"title": {
"type": "keyword"
},
"source_type": {
"type": "keyword"
},
"content": {
"type": "text",
"fields": {
"en": {
"type": "text",
"analyzer": "standard"
},
"zh": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
}

insert

接着,我们在news这个index中插入4条示例数据,其中前两条为中文,后两条为英文。

插入第一条数据:

1
2
3
4
5
6
PUT news/_doc/1
{
"source_type": "澎湃",
"title": "“具身智能”席卷世界机器人大会,王田苗:大部分其实是“具身技能”",
"content": "当“具身智能”成为2024世界机器人大会众人热议的焦点时,北京航空航天大学机器人研究所名誉所长王田苗提出了不一样的视角。他认为这次展会,展示的大部分是垂直领域的具身技能。现阶段,对于具身智能机器人或人形机器人,业界基本停留在对通用领域的探索上。具身智能(Embodied Intelligence)强调机器人通过综合感知、推理和自主决策,实现多任务处理和复杂环境中的人机交互,具备广泛的认知能力;而具身技能(Embodied Skills)更聚焦于特定场景下的专业化能力,旨在高效完成特定任务,应用更垂直、商业化更容易。业内认为,具身智能侧重“广而全”的智能化,具身技能则注重“专而精”的能力。现为北航机器人研究所名誉所长,中关村智友研究院院长的王田苗在机器人行业已深耕三十多年。2020年,王田苗联合十五位科学家发起成立了“智友科学家基金”,重点关注具身智能、机器人、机器人上游核心部件等领域。"
}

插入第二条数据:

1
2
3
4
5
6
PUT news/_doc/2
{
"source_type": "澎湃",
"title": "记录中国|福建永春:“反向旅游”潮下的宝藏小城",
"content": "盛夏,夜幕降临,福建永春县的五里古街灯火通明,当地市民和游客陆续到来,这条全长约590米的传统街区逐渐热闹了起来。“这个暑假的自然客流变多了。”永春五里街历史文化街区商铺老板林宏对记录中国团队称。五里街古集镇系永春县一个最早的商业市场。据《永春县志》称,民国初,以其地距离县城五华里而改称五里街,是永春、德化、大田一带货物集散地。作为海上丝绸之路水陆交汇的重要节点,五里古街曾以“无永不开市”名扬海内外,承载着众多华侨华人的乡愁记忆。百年来,这里承担着周边的德化、大田、永安、三明、尤溪、漳平的山货与厦门、泉州、晋江等地海货的交换重任,聚集了来自福建内外的数百商户,曾被誉为“闽南商贸重镇”。彼时,德化陶瓷、大田山货纷纷齐聚到此,再装船运往泉州沿海码头,部分商品还顺流而下,直接销往海外;沿海的盐、海产品、布匹等货物,通过水路运往此处,转至周边内地出售。自2018年起,永春县当地政府积极推进五里古街的修复改造工作,力图借此重现永春的历史与文化记忆,活化古街,以此来增强文化归属感。2024年1月7日,历时5年的重修和改造,五里古街正式开街迎客,通过举办各类活动为其“引流”,这座百年古街逐步被外界看见。今年“五一”期间,通过举办的“状元巡游”和“魁星祈礼”等活动吸引了许多外地游客的到来,让这座百年古街意外走红,更让过去不被人熟知的永春进入游客的视野,一举成为“反向旅游”潮下的宝藏小城。“我们正在努力恢复五里街的往日风采。”永春县一位党政干部对记录中国团队称。"
}

插入第三条数据:

1
2
3
4
5
6
PUT news/_doc/3
{
"source_type": "google news",
"title": "5 reasons why I use Python instead of Excel for visualizing data",
"content": "Microsoft Excel has been a darling of businesses and individuals for data analysis. That said, Python has been gaining popularity among professionals due to its scalability, flexibility, and advanced visualization. While Python was built to automate boring stuff, the programming language has become a go-to solution for many in web development, machine learning, and, of course, data analysis.Python’s extensive libraries and capabilities can deliver a significant upgrade to anyone looking for better data visualization. Here are the prime reasons why I have moved from relying solely on Excel to adopting Python as my preferred tool for data manipulation."
}

插入第四条数据:

1
2
3
4
5
6
PUT news/_doc/4
{
"source_type": "google news",
"title": "Hurricane Hone soaks Hawaii with flooding rain; another storm approaching",
"content": "Dual hurricane threats are zeroing in on Hawaii, a rare combination that could bring impactful rain and winds to the islands twice within a week.The Big Island of Hawaii was under a tropical storm warning until it was discontinued early afternoon Sunday after Hurricane Hone had passed south of the island, with its sustained winds down to 80 mph. The storm had gained Category 1 status overnight and made its presence felt despite not delivering a direct hit.Widespread rainfall of 10 to 15 inches has already fallen across windward Big Island over the past 24 hours, with some locally higher amounts of 18 inches or more, the National Weather Service said near 11 a.m. Hawaii time. Additional rainfall estimates of 3 to 5 inches will keep a moderate to high threat of flash flooding today over much of Hawaii County."
}

对于content字段,如果搜索文本(query)为中文,则使用ik分词器;如果为英语,则使用Standard Analyzer。至于语言检测,我们可以简单地认为,如果query中含有汉字,则为中文(该语言检测逻辑较为简单,可优化)。

以下是使用Python实现的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# -*- coding: utf-8 -*-
from elasticsearch import Elasticsearch

es_client = Elasticsearch(hosts=["http://localhost:9200"])


# 创建函数,实现功能: 判断文本中是否含有汉字,则返回zh; 反之则返回en
def judge_language(text: str) -> str:
for char in text:
if '\u4e00' <= char <= '\u9fff':
return 'zh'
return 'en'


# 创建创建,实现功能:输入query,根据语言使用对应的分词器,返回搜索结果
def search_by_query(query: str) -> list:
language = judge_language(query)
search_query = {
"query": {
"multi_match": {
"query": query,
"fields": [
f"content.{language}"
]
}
}
}
result = es_client.search(index="news", body=search_query)
# 返回搜索结果,只返回hits中的source部分中的title和source_type
return [{"title": hit["_source"]["title"], "source_type": hit["_source"]["source_type"]}
for hit in result["hits"]["hits"]]


if __name__ == '__main__':
print("====================================")
query1 = "福建旅游"
print(f"搜索返回条数:{len(search_by_query(query1))}")
print(search_by_query(query1))
print("====================================")
query2 = "hurricane weather"
print(f"搜索返回条数:{len(search_by_query(query2))}")
print(search_by_query(query2))
print("====================================")

返回结果如下:

1
2
3
4
5
6
====================================
搜索返回条数:1
[{'title': '记录中国|福建永春:“反向旅游”潮下的宝藏小城', 'source_type': '澎湃'}]
====================================
搜索返回条数:1
[{'title': 'Hurricane Hone soaks Hawaii with flooding rain; another storm approaching', 'source_type': 'google news'}]

总结

在ElasticSearch中,针对多语言内容的搜索需求,可以通过设置多字段的方式,为同一个字段使用不同的分词器。在上面的例子中,我们为content字段分别配置了en和zh两个子字段,分别使用Standard Analyzer和ik分词器,从而支持了英文和中文内容的精确搜索。

通过在搜索时动态判断输入语言并选择合适的分词器,我们能够实现对混合语言内容的有效检索。这种方法适用于需要处理多语言文本的场景,如新闻、博客等内容丰富且语言多样的数据平台。

你可以根据实际的应用需求,进一步优化语言检测的逻辑,或添加更多的分词器,以处理其他语言或特殊的文本内容。此外,在实际项目中,还可以结合其他ElasticSearch功能,如同义词扩展、自定义分词器等,以进一步提升搜索的精度和用户体验。


ElasticSearch入门之对单个字段使用多个分词器
https://percent4.github.io/ElasticSearch入门之对单个字段使用多个分词器/
作者
Jclian91
发布于
2024年11月13日
许可协议