【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过滤器:对切分的单词进行加工。

指定分词器
  • 通过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"
                }
            }
        }
    }
    
测试分词效果

analyze API

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
  • 查询texttext.english字段,并结合得分。

文本字段在第一个文件中包含术语fox,在第二个文件中包含foxes。text.english字段在两个文档中都包含fox,因为foxes被单词汇化为fox。

查询字符串也由标准分析器对文本字段进行分析,并由英语分析器对text.english字段进行分析。干系字段允许对狐狸的查询也匹配只包含fox的文档。这使我们能够匹配尽可能多的文件。通过同样查询未单词化的“文本”字段,我们提高了与“fox”完全匹配的文档的相关性得分。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Term查询是Elasticsearch中一种基本的查询方式,用于查询一个字段中包含指定关键词的文档,类似于MySQL中的等值查询。使用Term查询时,可以对字段进行完全匹配,且区分大小写。其基本语法如下所示: ``` GET /{index}/_search { "query": { "term": { "{field}": "{value}" } } } ``` 其中,`{index}`表示查询的索引名称,`{field}`表示需要查询的字段,`{value}`表示需要匹配的值。Term查询只能用于匹配该属性的单个值,若想匹配多个值,可以使用Terms查询Terms查询的基本语法如下所示: ``` GET /{index}/_search { "query": { "terms": { "{field}": [ "{value1}", "{value2}", "{value3}" ] } } } ``` 在Java代码中,可以使用`termsQuery`方法来构建Terms查询,如下所示: ```java TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("field", "value1", "value2", "value3"); searchSourceBuilder.query(termsQueryBuilder); ``` Term查询还可以配置其他参数,如超时时间等。在Java代码中,可以通过设置`timeout`来指定查询超时时间,如下所示: ```java searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); ``` 以上是关于Elasticsearch Term查询的基本用法和示例代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Elaticsearch查询 -Term查询](https://blog.csdn.net/weixin_43796428/article/details/131283196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值