elasticsearch全文搜索索引结构示例

elasticsearch是经常用到的文档索引工具,使用方便快捷。

之前介绍了如何增删改索引结构

https://blog.csdn.net/liliang199/article/details/155574706

这里进一步示例在创建索引后,如何全文搜索索引结构。

所用索引数据初始化自上述内容,详细过程参考上述连接。

这里所用示例代码参考和修改自网络资料。

1 分词器分析

elasticsearch全文检索依赖分词器对输入文本进行分词,然后依据分词在文档库中进行匹配。

1.1 elasticsearch分词

elasticsearch常用的分词器罗列如下:

standard是默认分词器,对单个字符进行切分,查全率高,准确度较低。

IK 分词器 ik_max_word,查全率与准确度较高,性能高,业务中普遍采用的中文分词器。

IK 分词器 ik_smart,切分力度较大,准确度与查全率不高,但是查询性能较高。

Smart Chinese 分词器,查全率与准确率性能较高。

hanlp 中文分词器,切分力度较大,准确度与查全率不高,但是查询性能较高。

Pinyin 分词器,针对汉字拼音进行的分词器,与上面介绍的分词器稍有不同,在用拼音进行查询时查全率准确度较高。

如果要说你用standard之外的分词器,比如ik系列,需要自主下载和安装,参考链接如下所示

https://github.com/infinilabs/analysis-ik/blob/master/README.md

1.2 standard分词示例

这里应用standard分词器,示例elasticsearch的分词结果。

复制代码
# 要分析的文本内容
text = "ElasticSearch的应用场景."

# 自定义分词器的名称
analyzer_name = "standard"

response = es_client.indices.analyze(
    index=index,  # 替换为你的索引名
    body={
        # "analyzer": analyzer_name,
        "text": text
    }
)

print(response)
# 提取分词结果
tokens = [token["token"] for token in response["tokens"]]

# 打印分词结果
print(tokens)

输出如下所示

{'tokens': [{'token': 'elasticsearch', 'start_offset': 0, 'end_offset': 13, 'type': '<ALPHANUM>', 'position': 0}, {'token': '的', 'start_offset': 13, 'end_offset': 14, 'type': '<IDEOGRAPHIC>', 'position': 1}, {'token': '应', 'start_offset': 14, 'end_offset': 15, 'type': '<IDEOGRAPHIC>', 'position': 2}, {'token': '用', 'start_offset': 15, 'end_offset': 16, 'type': '<IDEOGRAPHIC>', 'position': 3}, {'token': '场', 'start_offset': 16, 'end_offset': 17, 'type': '<IDEOGRAPHIC>', 'position': 4}, {'token': '景', 'start_offset': 17, 'end_offset': 18, 'type': '<IDEOGRAPHIC>', 'position': 5}]}

'elasticsearch', '的', '应', '用', '场', '景'

2 match查询

2.1 match查询

match匹配查询属于全文查询,elasticsearch在处理全文搜索时,分析查询字符串,根据分词结果构建查询,返回查询结果。

match查询有三种类型,分别是布尔、短语和短语前缀,默认match查询是布尔类型。

elasticsearch引擎对查询字符串进行分词的过程,参考第一节分词器分析。

2.2 match示例

上一篇文章中,将数据导入elasticsearch,导入过程参考

https://blog.csdn.net/liliang199/article/details/155574706

导入完成后,title字段将会包含如下数据。

Elasticsearch 完全指南:原理、优势与应用场景

20个必知的PyTorch概念简单解释,带你快速入门"

查询问题为"Elasticsearch应用场景"

针对title字段的match查询代码示例如下。

复制代码
# 使用search查询数据
query = {
    "query": {
        "match": {
            "title": "ElasticSearch的应用场景",
        }
    },
    "from": 0,
    "size": 3
}
res = es_client.search(index=index, body=query)
print(res)

虽然输入"ElasticSearch的应用场景"不能完全匹配elasticsearch title字段存储文本。

然而,依然搜到数据。这说明match匹配不是精确检索,而是全文分词检索。

{'took': 28, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 2198, 'relation': 'eq'}, 'max_score': 6.528569, 'hits': [{'_index': 'es_index_test', '_id': '1', '_score': 6.528569, '_source': {'document_id': 6, 'title': '20个必知的PyTorch概念简单解释,带你快速入门', 'content': 'PyTorch是当今最重要且最受欢迎的深度学习框架之一。它基于Meta的Lua语言Torch库构建,并于2017年开源。自发布以来,该库已被用于构建几乎所有重要的现代AI创新,从特斯拉的自动驾驶汽车到OpenAI的ChatGPT。本文将从基础出发,系统阐述20个最重要的概念,以深化对PyTorch的理解。'}}, {'_index': 'es_index_test', '_id': '2', '_score': 0.0034088849, '_source': {'document_id': '2', 'title': 'Elasticsearch 完全指南:原理、优势与应用场景', 'content': 'Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式、RESTful 搜索和分析引擎。它是 Elastic Stack(ELK Stack)的核心组件,由 Elastic 公司开发和维护。'}}, {'_index': 'es_index_test', '_id': '3', '_score': 0.0034088849, '_source': {'document_id': '3', 'title': 'Elasticsearch 完全指南:原理、优势与应用场景', 'content': 'Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式、RESTful 搜索和分析引擎。它是 Elastic Stack(ELK Stack)的核心组件,由 Elastic 公司开发和维护。'}}]}}

3 match_phrase 搜索

3.1 match_phrase查询

match_phrase要求所有的分词必须同时出现在文档中,同时位置必须紧邻一致。

match_phrase查询时,elasticsearch首先分析即分词查询字符串,从分词后的文本中构建短语查询,这意味着必须匹配短语中的所有分词,并且保证各个分词的相对位置不变。

这里用的是standard分词器,对单个字符进行切分,查全率高,准确度较低。

为确保找到内容,需要引入slop参数调整。

3.2 match_phrase示例

match_phrase短语匹配查询示例如下。

所用查询问题为"Elasticsearch应用场景",与2.2所用查询问题一致。

slop=8时,查询未命中。

示例如下

复制代码
# 使用search查询数据
query = {
    "query": {
        "match_phrase": {
            "title": {
                  "query": "Elasticsearch应用场景",
                  "slop": 8,
                }
        }
    },
    "from": 0,
    "size": 3
}
res = es_client.search(index=index, body=query)
print(res)

输出如下所示,slop=8时显然未命中。

{'took': 23, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 0, 'relation': 'eq'}, 'max_score': None, 'hits': []}}

需要将slop设置为更大的数字,但有可能混入其他可能不太相关的文档。

slop=9命中

示例如下

复制代码
# 使用search查询数据
query = {
    "query": {
        "match_phrase": {
            "title": {
                  "query": "Elasticsearch应用场景",
                  "slop": 9,
                }
        }
    },
    "from": 0,
    "size": 3
}
res = es_client.search(index=index, body=query)
print(res)

输出示例如下所示。

{'took': 40, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 2197, 'relation': 'eq'}, 'max_score': 0.00057690963, 'hits': [{'_index': 'es_index_test', '_id': '2', '_score': 0.00057690963, '_source': {'document_id': '2', 'title': 'Elasticsearch 完全指南:原理、优势与应用场景', 'content': 'Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式、RESTful 搜索和分析引擎。它是 Elastic Stack(ELK Stack)的核心组件,由 Elastic 公司开发和维护。'}}, {'_index': 'es_index_test', '_id': '3', '_score': 0.00057690963, '_source': {'document_id': '3', 'title': 'Elasticsearch 完全指南:原理、优势与应用场景', 'content': 'Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式、RESTful 搜索和分析引擎。它是 Elastic Stack(ELK Stack)的核心组件,由 Elastic 公司开发和维护。'}}, {'_index': 'es_index_test', '_id': '4', '_score': 0.00057690963, '_source': {'document_id': '4', 'title': 'Elasticsearch 完全指南:原理、优势与应用场景', 'content': 'Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式、RESTful 搜索和分析引擎。它是 Elastic Stack(ELK Stack)的核心组件,由 Elastic 公司开发和维护。'}}]}}

4 精确查询

如果要实现精确查询,需要将字段设为keyword类,然后使用term精确匹配对应字段。

这里首先同时创建keyword、text索引字段,导入数据,然后示例term精确匹配查询过程。

4.1 创建索引

为对比分析,这里同时创建keywor和text索引字段。

具体为字段document_id创建keyword索引,为title为text索引。

示例代码如下。

复制代码
index = "es_index_key"

mapping = {
    "properties": {
        "document_id": {"type": "keyword", "store": True, "similarity": "boolean"},
        "title": {
            "type": "text"
        },
    }
}

print(es_client.indices.exists(index=index))

res = es_client.indices.create(
    index=index,
    mappings=mapping
)

print(res)

输出如下

False

{'acknowledged': True, 'shards_acknowledged': True, 'index': 'es_index_key'}

4.2 导入数据

然后为创建的索引,导入测试数据,示例代码如下。

复制代码
obj1 = {
        "document_id": "news_1",
        "title": u"The Ten Best Science Books of 2025",
        "content": u"In 2025, our science reporters followed the first confirmed glimpse of a colossal squid and a rare look at dinosaur blood vessels. We watched the odds of a future asteroid impact climb to higher-than-normal levels---then drop back down to zero. We parsed headlines on a blood test to detect cancer and a beloved pair of coyotes in New York City's Central Park. Throughout it all, many of us read extended works of science nonfiction, pulling back the curtain on tuberculosis, evolution and the Arctic....",
    }

obj2 = {
        "document_id": "news_2",
        "title": u"The 7 Most Groundbreaking NASA Discoveries of 2025",
        "content": u"In 2025, NASA faced unprecedented uncertainty as it grappled with sweeping layoffs, looming budget cuts, and leadership switch-ups. Despite all of that, the agency somehow still managed to do some seriously astonishing science.....",
    }
_id1 = 1
es_client.index(index=index, body=obj1, id=_id1)
_id2 = 2
es_client.index(index=index, body=obj2, id=_id2)

输出如下所示

ObjectApiResponse({'_index': 'es_index_key', '_id': '2', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 1, '_primary_term': 1})

4.3 term精确匹配

这里分别对keyword、text字段进行精确、模糊查询示例。

keyword类型字段使用term精确匹配有效,text类型字段使用term精确匹配无效。

1)keyword精确查询

使用keyword字段document_id的精确查询示例如下所示。

测试问题为document_id="news_2"

复制代码
query = {
  "query": {
    "term": {
      "document_id": "news_2"
    }
  }
}
res = es_client.search(index=index, body=query)
print(res)

输出如下,找到了数据。

{'took': 33, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 1, 'relation': 'eq'}, 'max_score': 1.0, 'hits': [{'_index': 'es_index_key', '_id': '2', '_score': 1.0, '_source': {'document_id': 'news_2', 'title': 'The 7 Most Groundbreaking NASA Discoveries of 2025', 'content': 'In 2025, NASA faced unprecedented uncertainty as it grappled with sweeping layoffs, looming budget cuts, and leadership switch-ups. Despite all of that, the agency somehow still managed to do some seriously astonishing science.....'}}]}}

对测试问题做些微小修改,document_id="news_2x"

复制代码
uery = {
  "query": {
    "term": {
      "document_id": "news_2 x"
    }
  }
}
res = es_client.search(index=index, body=query)
print(res)

输出如下,显然这时没有找到

{'took': 16, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 0, 'relation': 'eq'}, 'max_score': None, 'hits': []}}

这说明document_id的term精确匹配生效了。

2)text精确查询

这里,title字段采用text类型,这里对text进行term精确匹配,

测试问题如下

title= u"The 7 Most Groundbreaking NASA Discoveries of 2025"

结合4.2数据导入过程,测试问题与elasticsearch库中的title完全一样。

测试代码如下所示

复制代码
query = {
  "query": {
    "term": {
      "title": u"The 7 Most Groundbreaking NASA Discoveries of 2025",
    }
  }
}
res = es_client.search(index=index, body=query)
print(res)

输出如下,显然在titile正确情况下,依然没有找到数据。

{'took': 19, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 0, 'relation': 'eq'}, 'max_score': None, 'hits': []}}

3)text模糊查询

在term精确匹配失效的情况下,尝试对title字段进行模糊匹配。

测试问题不变,title= u"The 7 Most Groundbreaking NASA Discoveries of 2025"

测试代码如下所示。

复制代码
query = {
  "query": {
    "match": {
      "title": u"The 7 Most Groundbreaking NASA Discoveries of 2025",
    }
  }
}
res = es_client.search(index=index, body=query)
print(res)

输出如下,转为模糊查询后,就找到数据了。

这说明text类型字段不支持term精确匹配。

{'took': 37, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 2, 'relation': 'eq'}, 'max_score': 3.906169, 'hits': [{'_index': 'es_index_key', '_id': '2', '_score': 3.906169, '_source': {'document_id': 'news_2', 'title': 'The 7 Most Groundbreaking NASA Discoveries of 2025', 'content': 'In 2025, NASA faced unprecedented uncertainty as it grappled with sweeping layoffs, looming budget cuts, and leadership switch-ups. Despite all of that, the agency somehow still managed to do some seriously astonishing science.....'}}, {'_index': 'es_index_key', '_id': '1', '_score': 0.5623002, '_ignored': ['content.keyword'], '_source': {'document_id': 'news_1', 'title': 'The Ten Best Science Books of 2025', 'content': 'In 2025, our science reporters followed the first confirmed glimpse of a colossal squid and a rare look at dinosaur blood vessels. We watched the odds of a future asteroid impact climb to higher-than-normal levels---then drop back down to zero. We parsed headlines on a blood test to detect cancer and a beloved pair of coyotes in New York City's Central Park. Throughout it all, many of us read extended works of science nonfiction, pulling back the curtain on tuberculosis, evolution and the Arctic....'}}]}}

reference


elasticsearch增删改查索引结构示例

https://blog.csdn.net/liliang199/article/details/155574706

ElasticSearch查询 第四篇:匹配查询(Match)

https://www.cnblogs.com/ljhdo/p/4577065.html

elasticsearch7.x 的 python sdk,如何指定自定义的分词器查看分词后的结果

https://segmentfault.com/a/1190000043863785

Elasticsearch 中文分词器

https://developer.aliyun.com/article/848626

Elasticsearch 精确查询

https://www.echo.cool/docs/database/elasticsearch/elasticsearch-query/elasticsearch-exact-query/

【ElasticSearch】精确匹配text字段 用match加.keyword 或 term

https://blog.csdn.net/u012161251/article/details/120559438

IK Analysis for Elasticsearch and OpenSearch

https://github.com/infinilabs/analysis-ik/blob/master/README.md

相关推荐
有味道的男人6 分钟前
平衡接入京东关键词API利弊的核心策略
大数据·运维
ZKNOW甄知科技19 分钟前
IT自动分派单据:让企业服务流程更智能、更高效的关键技术
大数据·运维·数据库·人工智能·低代码·自动化
屿小夏.32 分钟前
【Elasticsearch】Elasticsearch的分片和副本机制
大数据·elasticsearch·jenkins
地瓜伯伯32 分钟前
elasticsearch性能调优方法原理与实战
人工智能·elasticsearch·语言模型·数据分析
黑客思维者37 分钟前
2025年AI垃圾(AI Slop)现象综合研究报告:规模、影响与治理路径
人工智能·搜索引擎·百度
张彦峰ZYF38 分钟前
探索数据的力量:Elasticsearch中指定链表字段的统计查询记录
搜索引擎·性能优化·es
Jinkxs38 分钟前
Gradle - 与Elasticsearch集成 构建搜索服务项目
大数据·elasticsearch·搜索引擎
DBA大董2 小时前
云环境部署TDengine的那些坑
大数据·时序数据库·tdengine
阿坤带你走近大数据2 小时前
数据湖的构建实施方法论
大数据·数据湖·湖仓一体
安徽必海微马春梅_6688A2 小时前
实验a 信息化集成化生物信号采集与处理系统
大数据·人工智能·深度学习·信号处理