ES查询知识小结

这篇具有很好参考价值的文章主要介绍了ES查询知识小结。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ES 查询总结

【注意】 以下查询语法都是在 kibina 上直接进行查询的语法。 关于如何创建索引和如何创建文档的就不在这里叙述了。

ES的版本 8以前有这个 type 概念, type 是这个每一个字段的类型 。

type:字段数据类型,常见的简单类型有:

  • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
  • 数值:long、integer、short、byte、double、float、
  • 布尔:boolean
  • 日期:date
  • 对象:object

1. ES查询总览

es查询索引结构,elasticSearch,elasticsearch,数据库,java

2. 查询所有信息 match_all

这个查询是不需要查询条件的 , 是查询该索引中的所有的文档。

【索引和mysql中的表对应, ES中的一个文档和mysql中的一条数据对应 】

GET / 索引库名称/_search

{

​ “query” : {

​ “match_all” : { }

​ }

}

示例:

索引库名称: test_index2 索引结构如下:
es查询索引结构,elasticSearch,elasticsearch,数据库,java

GET /test_index2/_search
{
  "query":{
    "match_all": {}
  }
}

es查询索引结构,elasticSearch,elasticsearch,数据库,java

3. 查询单个字段 模糊匹配 match

分词介绍:

【分词器】 标准分词器: 对中文,只会分为一个字一个字,不会进行智能分词。

​ eg: 我爱学习 — > 我 , 爱 , 学, 习 .

​ 对英文, 会根据空格或者其他字符非字母进行分词,

​ eg: i like study es —> i , like , study , es

(2) 中文分词

es查询索引结构,elasticSearch,elasticsearch,数据库,java

(2) 英文分词

es查询索引结构,elasticSearch,elasticsearch,数据库,java

(3) 中应混合

es查询索引结构,elasticSearch,elasticsearch,数据库,java

(4) 带有符号的, 会以符号进行分词.

es查询索引结构,elasticSearch,elasticsearch,数据库,java

match 查询:

会把当前搜索的关键词条, 进行分词, 然后按照

查询的字段类型: ① 被搜索的字段的 type 的类型 最常用的是text 类型。

​ ② 其他类型的话, 查询等于term查询, 精确匹配搜索。

(1)字段类型是 text 类型, 那么搜索的词条 会先被分词, 然后和库里被分好词的字段进行匹配。最后根据相关度算分排名 从大到小

标准分词器: 对中文 “西安” 进行分词, 那么就会分为 西 ,安 两个字,然后和库里的数据进行比对。 把name字段中包含 西 和 安这2个字的数据都给搜索出来。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

(2) 类型是其他类型,搜索等于精确匹配查询, 就是完全匹配:被搜索的关键词条要和对应的数据完全匹配才可以~

查询desc 字段, 该字段类型是: keyword 类型, 只有完全匹配才可以搜索到。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

如果只搜索 “基础” , 是搜索不到结果的。 如果desc 是text类型那么就可以。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

4. 多字段 模糊查询 match_multip

根据多个字段去查找这个关键词, 只要符合其中任何一个字段都可以

GET /indexName/_search
{
  "query": {
    "multi_match": {
      "query": "TEXT",
      "fields": ["FIELD1", " FIELD12"]
    }
  }
}

eg: 要根据 西安去查询 name (type = text)字段 , desc (type = keyword)

就会分别去查询 根据 “西安” 对name 字段进行一个分词搜索, 把name字段中带 西 , 安 的都搜索出来.

但是对 desc 字段只会是进行一个精确匹配, 完全匹配。 只有desc的值 完全等于 西安 的才会被查询到。

最后把这两个字段查询到的所有的数据进行一个 取并集的操作。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

5. 短语模糊查询 match_prase

(1)如果是keyword类型, 那么还是等同于精确查询, 必须要完全匹配才可以。

(2)如果是text类型, 会对搜索的词条进行分词 , 而且还要保证词条之间的相对位置一致才可以被搜索到。 且分出来的每个词是要完全匹配的,才可以。

比如: 有一条数据: name = i like study es 。

搜索: name = like study , 就可以搜索到该数据,

但是搜索 like es , 就搜索不到, 因为这个like 和 es 之间的相对位置 和 被搜索的数据的相对位置不一样。 且与中间的符号无关,

以及连续几个符号无关。

举例:

es查询索引结构,elasticSearch,elasticsearch,数据库,java

如果搜索 hah +wowo , 是搜索不到的。 因为中间隔了一个 hiehei ,

如果搜索 hah???+heihei , 是可以搜索到的。

如果搜索hah?heihei, 也是可以的, 因为多个符号不影响,分词只会有2部分。 也是可以搜索到的。

如果搜索ha?hiehei, 搜索不到, 因为ha 无法和 hah 匹配, 就是分出来的每一个词都要和目标数据分词完全对应才可以。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

7. 短语模糊前缀查询 match_prase_prefix

这个并非真正的前缀查询, 只是这个搜索的关键词条分词后的最后一个词可以实现前缀模糊匹配.

eg: i like reading and swimming .

如果搜 like read , 那么也是可以搜索出来的. 如果是 match_prase 查询的话, 只有查 like reading 才可以搜索出来.

除了这一条, 其他和match_prase 一模一样.

这个前缀只是针对于 type = text 类型字段进行查询 , keyword 类型直接报错.

es查询索引结构,elasticSearch,elasticsearch,数据库,java

6. 单字段精确查询 term

term 查询 , 精确查询一般是查找keyword、数值、日期、boolean等类型字段。 所以 不会 对搜索条件分词

先查询了所有的内容。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

先搜索一个字段类型为 text 类型的字段,搜索name 字段 , 值为 “西安” 的。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

可以看到并没有搜索到数据, 那么为什么呢?

因为在库中这个字段是text类型, 对 “西安”, 进行了分词, 那么在库里存的是 “ 西 ”, “安” , 没有 “西安” 这个词条, 所以搜索不到。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

那么我们可以看到对于text 类型 , 分词的类型也是可以使用term搜索的。 不过大多数要使用term查询, 字段类型还是不要为text类型, 不然就失去了精确匹配查询的意义了。

7. 单字段多值精确查询 terms

如果我想查询 一个字段的多个数据, 比如想查询desc中既有西安, 又有上海的数据。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

8. 单字整体模糊匹配 wildcard 查询

支持通配符: * * 匹配任意字符, ? 匹配一个或多个。

这个查询有点像我们 mysql的 like查询, select name where name like “%西安%” ;

对于text类型 是去匹配字段值的每一个词条, 而对于keyword 类型则是匹配对应的字段的值, 匹配的方式就是模糊匹配, 类似于like

而且这个搜索对于我们输入的关键词条是不会分词的。

但是是需要我们给搜索的字段加上 * 西安 * , 这样去搜

因为如果字段类型是text类型的话, 匹配的时候是不会存这个特殊符号的, 所以如果你想搜索的内容是带特殊符号的, 最好使用keyword类型的字段。 不然很多情况会搜索失效。

否则会出现这样的情况: text类型: 文档 : --> name = haha???heihei+++

搜索: name = * haha?* ,但是词条中没有这个 haha? , 只有haha , heihei

但是如果是keyword类型, 那么字段是作为一个整体建立索引的, 是可以直接进行匹配的。

es查询索引结构,elasticSearch,elasticsearch,数据库,java

9. 复合查询 - 多字段-多条件查询

9.1 布尔查询

布尔查询是一个或多个查询子句的组合,每一个子句就是一个子查询。子查询的组合方式有:

  • must:必须匹配每个子查询,类似 “与”
  • should:选择性匹配子查询,类似 “或”
  • must_not:必须不匹配,不参与算分,类似“非”
  • filter:必须匹配,不参与算分

大概分3类:

① 必须匹配: 与操作: must (算分) , filter(不算分)

②选择性匹配: 或操作: should (算分)

③必须不匹配: 非操作, must_not (不算分)

比如在搜索酒店时,除了关键字搜索外,我们还可能根据品牌、价格、城市等字段做过滤:

es查询索引结构,elasticSearch,elasticsearch,数据库,java

每一个不同的字段,其查询的条件、方式都不一样,必须是多个不同的查询,而要组合这些查询,就必须用bool查询了。

需要注意的是,搜索时,参与打分的字段越多,查询的性能也越差。因此这种多条件查询时,建议这样做:

  • 搜索框的关键字搜索,是全文检索查询,使用must查询,参与算分
  • 其它过滤条件,采用filter查询。不参与算分
1)语法示例:
GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"city": "上海" }}
      ],
      "should": [
        {"term": {"brand": "皇冠假日" }},
        {"term": {"brand": "华美达" }}
      ],
      "must_not": [
        { "range": { "price": { "lte": 500 } }}
      ],
      "filter": [
        { "range": {"score": { "gte": 45 } }}
      ]
    }
  }
}
2)示例

需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店。

分析:

  • 名称搜索,属于全文检索查询,应该参与算分。放到must中
  • 价格不高于400,用range查询,属于过滤条件,不参与算分。放到must_not中
  • 周围10km范围内,用geo_distance查询,属于过滤条件,不参与算分。放到filter中

es查询索引结构,elasticSearch,elasticsearch,数据库,java

3)小结

bool查询有几种逻辑关系?

  • must:必须匹配的条件,可以理解为“与”
  • should:选择性匹配的条件,可以理解为“或”
  • must_not:必须不匹配的条件,不参与打分
  • filter:必须匹配的条件,不参与打分
9.2 算分函数查询
9.2.1 相关性算分

当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。

例如,我们搜索 “虹桥如家”,结果如下:

[
  {
    "_score" : 17.850193,
    "_source" : {
      "name" : "虹桥如家酒店真不错",
    }
  },
  {
    "_score" : 12.259849,
    "_source" : {
      "name" : "外滩如家酒店真不错",
    }
  },
  {
    "_score" : 11.91091,
    "_source" : {
      "name" : "迪士尼如家酒店真不错",
    }
  }
]

在elasticsearch中,早期使用的打分算法是TF-IDF算法,公式如下:
es查询索引结构,elasticSearch,elasticsearch,数据库,java

在后来的5.1版本升级中,elasticsearch将算法改进为BM25算法,公式如下:

es查询索引结构,elasticSearch,elasticsearch,数据库,java

TF-IDF算法有一各缺陷,就是词条频率越高,文档得分也会越高,单个词条对文档影响较大。而BM25则会让单个词条的算分有一个上限,曲线更加平滑:

es查询索引结构,elasticSearch,elasticsearch,数据库,java

小结:elasticsearch会根据词条和文档的相关度做打分,算法由两种:

  • TF-IDF算法
  • BM25算法,elasticsearch5.1版本后采用的算法
9.2.2.算分函数查询

根据相关度打分是比较合理的需求,但合理的不一定是产品经理需要的。

以百度为例,你搜索的结果中,并不是相关度越高排名越靠前,而是谁掏的钱多排名就越靠前。

要想认为控制相关性算分,就需要利用elasticsearch中的function score 查询了。

1)语法说明

es查询索引结构,elasticSearch,elasticsearch,数据库,java

function score 查询中包含四部分内容:

  • 原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
  • 过滤条件:filter部分,符合该条件的文档才会重新算分
  • 算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
    • weight:函数结果是常量
    • field_value_factor:以文档中的某个字段值作为函数结果
    • random_score:以随机数作为函数结果
    • script_score:自定义算分函数算法
  • 运算模式算分函数 的结果、原始查询的相关性算分,两者之间的运算方式,包括:
    • multiply:相乘
    • replace:用function score替换query score
    • 其它,例如:sum、avg、max、min

function score的运行流程如下:

  • 1)根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)
  • 2)根据过滤条件,过滤文档
  • 3)符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)
  • 4)将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。

因此,其中的关键点是:

  • 过滤条件:决定哪些文档的算分被修改
  • 算分函数:决定函数算分的算法
  • 运算模式:决定最终算分结果
2)示例

需求:给“如家”这个品牌的酒店排名靠前一些

翻译一下这个需求,转换为之前说的四个要点:

  • 原始条件:不确定,可以任意变化
  • 过滤条件:brand = “如家”
  • 算分函数:可以简单粗暴,直接给固定的算分结果,weight
  • 运算模式:比如求和

因此最终的DSL语句如下:

GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {  .... }, // 原始查询,可以是任意条件
      "functions": [ // 算分函数
        {
          "filter": { // 满足的条件,品牌必须是如家
            "term": {
              "brand": "如家"
            }
          },
          "weight": 2 // 算分权重为2
        }
      ],
      "boost_mode": "sum" // 加权模式,求和
    }
  }
}

测试,在未添加算分函数时,如家得分如下:

es查询索引结构,elasticSearch,elasticsearch,数据库,java

添加了算分函数后,如家得分就提升了:

es查询索引结构,elasticSearch,elasticsearch,数据库,java

3)小结

function score query定义的三要素是什么?文章来源地址https://www.toymoban.com/news/detail-790233.html

  • 过滤条件:哪些文档要加分
  • 算分函数:如何计算function score
  • 加权方式:function score 与 query score如何运算

到了这里,关于ES查询知识小结的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • es elasticsearch 九 索引index 定制分词器 type结构后期弃用原因 定制动态映射 动态映射模板 零停机重建索引

    es elasticsearch 九 索引index 定制分词器 type结构后期弃用原因 定制动态映射 动态映射模板 零停机重建索引

    目录 索引index 定制分词器 Type底层结构及弃用原因 定制 dynamic mapping 定制dynamic mapping template 动态映射模板 零停机重建索引 生产环境应该度别名数据 索引index Put /index Stings 分片 Mapping 映射 Aliases 别名 增加 Put my_index2 {        \\\"settings\\\":{           \\\"number_of_shards\\\":3,      

    2024年02月06日
    浏览(10)
  • 原生语言操作和spring data中RestHighLevelClient操作Elasticsearch,索引,文档的基本操作,es的高级查询.查询结果处理. 数据聚合.相关性系数打分

    原生语言操作和spring data中RestHighLevelClient操作Elasticsearch,索引,文档的基本操作,es的高级查询.查询结果处理. 数据聚合.相关性系数打分

    ​ Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasti

    2024年02月05日
    浏览(71)
  • ES(elasticsearch)删除指定索引

    ES(elasticsearch)删除指定索引

    需要删除指定的索引 执行命令 比如:DELETE /mysql-status_-2023.06 执行结果: 执行命令 比如:HEAD /mysql-status_-2023.06 执行结果: 说明已经删除完毕 删除命令: DELETE /索引名 查看是否删除成功: HEAD /索引名 查看索引命令: GET /索引名称 批量查看索引命令: GET /索引名称1,索引名称

    2024年02月11日
    浏览(13)
  • 【ES】Elasticsearch-深入理解索引原理

    【ES】Elasticsearch-深入理解索引原理

    索引(Index) ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新

    2024年02月04日
    浏览(10)
  • elasticsearch(三)-- 理解ES的索引操作

    elasticsearch(三)-- 理解ES的索引操作

    上一章我们主要学习了es的几个客户端,那么我们后面也主要通过kibana客户端、HighLevelClient高级客户端这两个来学习es. 这一章的学习我们主要是学习一些Elasticsearch的基础操作,主要是深入一些概念,比如索引的具体操作,映射的相关语法,对数据类型,文档的操作。那么主要

    2024年02月04日
    浏览(8)
  • 【elasticsearch】修改es集群的索引副本数量

    最近海外es集群进行调整,从3节点变成了单节点。所以需要将集群模式改为单点模式,并需要将es 集群的全部索引副本个数改为0,不然会有很多未分配的分片,导致集群状态为 yellow 。 1. 先将现有的index的副本数量为0个 此步骤是为了解决现有的索引副本数。 2. 创建模板匹配

    2024年02月11日
    浏览(12)
  • elasticsearch修改es集群的索引副本数量

    最近es集群进行调整,从2节点变成了单节点。所以需要将集群模式改为单点模式,并需要将es 集群的全部索引副本个数改为0,不然会有很多未分配的分片,导致集群状态为 yellow。 1. 先将现有的index的副本数量为0个 此步骤是为了解决现有的索引副本数。 2. 创建模板匹配所有

    2024年02月08日
    浏览(15)
  • es elasticsearch 新增更新索引,新增更新文档

    先新增索引 新增映射  或者上述两步和为一步(创建索引,及创建mapping) 只能增加原有不存在的字段 创建一个全新的索引,映射包含调整后的字段或类型 将原有索引的数据迁移到新的索引 删除原有索引 将新的索引的别名设置为原来索引相同名称 创建一个 重建文档(全量

    2024年02月11日
    浏览(13)
  • 【ES】Elasticsearch核心基础概念:文档与索引

    【ES】Elasticsearch核心基础概念:文档与索引

    es的核心概念主要是:index(索引)、Document(文档)、Clusters(集群)、Node(节点)与实例,下面我们先来了解一下Document与Index。 在讲解Document与Index概念之前,我们先来了解一下RESTful APIs,因为下面讲解Document和Index的时候会使用到。 当我们把es服务器启动起来之后,要怎么调用呢?

    2024年02月05日
    浏览(11)
  • 【ElasticSearch】更新es索引生命周期策略,策略何时对索引生效

    【ElasticSearch】更新es索引生命周期策略,策略何时对索引生效

    大家好,我是好学的小师弟,今天和大家讨论下更新es索引生命周期策略后,策略何时对索引生效 结论: 若当前索引已应用策略A(旧),更新完策略A后,新的策略A会立即对原来的已经应用该策略的索引生效;若当前索引符合新策略A的生命周期变化条件,则会自动进入下一阶段

    2024年02月07日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包