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

相关推荐
千里码aicood9 小时前
计算机大数据、人工智能与智能系统开发定制开发
大数据·人工智能·深度学习·决策树·机器学习·森林树
非著名架构师11 小时前
城市通风廊道的科学依据:气候大数据如何指导未来城市规划设计
大数据·风光功率预测·高精度气象数据
IIIIIILLLLLLLLLLLLL11 小时前
Hadoop集群时间同步方法
大数据·hadoop·分布式
搞科研的小刘选手11 小时前
【经管专题会议】第五届大数据经济与数字化管理国际学术会议(BDEDM 2026)
大数据·区块链·学术会议·数据化管理·经济理论
蓝耘智算12 小时前
GPU算力租赁与算力云平台选型指南:从需求匹配到成本优化的实战思路
大数据·人工智能·ai·gpu算力·蓝耘
liliangcsdn12 小时前
如何用bootstrap模拟估计pass@k
大数据·人工智能·bootstrap
DMD16812 小时前
AI赋能旅游与酒店业:技术逻辑与开发实践解析
大数据·人工智能·信息可视化·重构·旅游·产业升级
Elastic 中国社区官方博客13 小时前
Elasticsearch 中使用 NVIDIA cuVS 实现最高快 12 倍的向量索引速度:GPU 加速第 2 章
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索·数据库架构
jqpwxt13 小时前
启点智慧景区多商户分账系统,多业态景区收银管理系统
大数据·旅游