ES实战Term查询未命中问题
Posted 顧棟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES实战Term查询未命中问题相关的知识,希望对你有一定的参考价值。
文章目录
Term查询未命中问题
问题
Search使用term查询未命中数据
采用索引自动创建模式-写入数据
POST gudong20230111/_doc
"fundCode":"SSS000"
term查询
GET /gudong20230111/_doc/_search
"query":
"bool":
"must": [
"term": "fundCode":"SSS000"
]
结果未命中
"took": 2,
"timed_out": false,
"_shards":
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
,
"hits":
"total": 0,
"max_score": null,
"hits": []
检查索引配置
GET /gudong20230111/_mappings
"gudong20230111":
"mappings":
"_doc":
"properties":
"fundCode":
"type": "text",
"fields":
"keyword":
"type": "keyword",
"ignore_above": 256
发现fundCode
字段类型是text,未指明分词器,会采用默认的标准分词器进行文本分析。
检查文本分析效果
通过_analyze api得到文本分词效果
POST _analyze
"analyzer": "standard",
"text": "SSS000"
"tokens": [
"token": "sss000",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
]
发现分析出的词汇是小写的,所以在使用大写的数据进行查询的时候,会查询不到,
总结
term查询
term级别查询是对存储在倒置索引中的单词或词汇进行操作,并且在执行前仅对具有normalizer
属性的keyword
类型的字段进行规范化处理。term级别查询通常用于数字、日期和枚举等结构化数据,而不是全文字段。
term查询的前提
字段的文本需要经过文本分析,形成词汇。需要字段类型为text,采用默认标准分词器或者自定义分词器。
默认分词器-标准分词器
standard
分析器是默认的分词器,如果没有指定则使用。 它提供基于语法的标记化(基于 Unicode 标准附件 #29 中指定的 Unicode 文本分段算法),并且适用于大多数语言。
内置的标准分析器包含以下部分:
-
分词器:英文分词可以根据空格将单词分开,中文分词比较复杂,可以采用机器学习算法来分词。
-
Token过滤器:对切分的单词进行加工。
- Standard Token Filter:一个标准类型的标记过滤器,对使用标准标记器提取的标记进行规范化。是一个保留项,啥都不干,在6.5.0之后已经不建议使用
- Lower Case Token Filter:默认的都是将英文转成小写的
- Stop Token Filter (disabled by default)
指定分词器
-
通过mapping指定
PUT my_index "mappings": "_doc": "properties": "code": "type": "keyword" , "name": "type": "text", "analyzer": "english", "search_analyzer": "standard"
-
URL Search上使用analyer参数
-
Request Body Search 中DSL语法
GET gudong20230111/_doc/_search "query": "match": "fundCode": "query": "SSS000", "analyzer": "standard"
测试分词效果
POST _analyze
"analyzer": "whitespace",
"text": "The quick brown fox."
POST _analyze
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ],
"text": "Is this déja vu?"
不进行分词
将字段变为keyword,不会进行分词操作,keyword主要用于聚合和排序
text主要用于全文检索。
字段即分词又不分词
为不同的目的以不同的方式对同一字段进行索引往往是有用的。这就是多字段的目的。例如,一个字符串字段可以被映射为text字段用于全文搜索,也可以被映射为keyword字段用于排序或聚合。
PUT my_index
"mappings":
"_doc":
"properties":
"city":
"type": "text",
"fields":
"raw":
"type": "keyword"
PUT my_index/_doc/1
"city": "New York"
PUT my_index/_doc/2
"city": "York"
GET my_index/_search
"query":
"match":
"city": "york"
,
"sort":
"city.raw": "asc"
,
"aggs":
"Cities":
"terms":
"field": "city.raw"
city.raw
字段是city
字段的一个keyword
类型版本。city
字段可用于全文搜索city.raw
字段可用于排序和聚合
多字段的另一个用例是以不同的方式分析同一字段,以提高相关性。例如,我们可以用标准分析器对一个字段进行索引,该分析器将文本分解成单词,并再次用英语分析器将单词分成词根形式。
PUT my_index
"mappings":
"_doc":
"properties":
"text":
"type": "text",
"fields":
"english":
"type": "text",
"analyzer": "english"
PUT my_index/_doc/1
"text": "quick brown fox"
PUT my_index/_doc/2
"text": "quick brown foxes"
GET my_index/_search
"query":
"multi_match":
"query": "quick brown foxes",
"fields": [
"text",
"text.english"
],
"type": "most_fields"
text
字段使用standard
分析器。text.english
字段使用english
分析器。- 写入两个文档,一个是
fox
,另一个是foxes
。 - 查询
text
和text.english
字段,并结合得分。
文本字段在第一个文件中包含术语fox,在第二个文件中包含foxes。text.english字段在两个文档中都包含fox,因为foxes被单词汇化为fox。
查询字符串也由标准分析器对文本字段进行分析,并由英语分析器对text.english字段进行分析。干系字段允许对狐狸的查询也匹配只包含fox的文档。这使我们能够匹配尽可能多的文件。通过同样查询未单词化的“文本”字段,我们提高了与“fox”完全匹配的文档的相关性得分。
以上是关于ES实战Term查询未命中问题的主要内容,如果未能解决你的问题,请参考以下文章
ElasticSearch:给定一个文档和一个查询,相关性得分是多少?
【ES从入门到实战】十七、全文检索-ElasticSearch-进阶-aggregations聚合分析
es 基础概念总结 —— Request Body Search