elasticsearch的使用(二)

news2024/9/29 11:27:01

DSL查询

Elasticsearch的查询可以分为两大类:

  • 叶子查询(Leaf query clauses):一般是在特定的字段里查询特定值,属于简单查询,很少单独使用。

  • 复合查询(Compound query clauses):以逻辑方式组合多个叶子查询或者更改叶子查询的行为方式

语法示例:

GET /{索引库名}/_search
{
  "query": {
    "查询类型": {
      // .. 查询条件
    }
  }
}

无条件查询的类型是:match_all:

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

获取到的结果

你会发现虽然是match_all,但是响应结果中并不会包含索引库中的所有文档,而是仅有10条。这是因为处于安全考虑,elasticsearch设置了默认的查询页数。 

叶子查询

叶子查询的类型也可以做进一步细分,详情大家可以查看官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/query-dsl.html

这里列举一些常见的,例如:

  • 全文检索查询(Full Text Queries):利用分词器对用户输入搜索条件先分词,得到词条,然后再利用倒排索引搜索词条。例如:

    • match

    • multi_match

  • 精确查询(Term-level queries):不对用户输入搜索条件分词,根据字段内容精确值匹配。但只能查找keyword、数值、日期、boolean类型的字段。例如:

    • ids

    • term

    • range

  • 地理坐标查询:用于搜索地理位置,搜索方式很多,例如:

    • geo_bounding_box:按矩形搜索

    • geo_distance:按点和半径搜索

全文检索查询

全文检索的种类也很多,详情可以参考官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/full-text-queries.html

match(匹配单个字段),语法如下:

GET /{索引库名}/_search
{
  "query": {
    "match": {
      "字段名": "搜索条件"
    }
  }
}

使用实例:

GET /items/_search
{
  "query": {
    "match": {
      "name": "手机"
    }
  }
}

查询结果

multi_match(匹配多个字段):语法如下

GET /{索引库名}/_search
{
  "query": {
    "multi_match": {
      "query": "搜索条件",
      "fields": ["字段1", "字段2"]
    }
  }
}

实例,我们搜索带华为二字的品牌与名字的商品 

GET /items/_search
{
  "query": {
    "multi_match": {
      "query": "华为",
      "fields": ["brand","name"]
    }
  }
}

精确查询

推荐查找keyword、数值、日期、boolean类型的字段。

详情可以查看官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/term-level-queries.html

term查询(精确查询某个字段的相同值的文档),语法如下:

GET /{索引库名}/_search
{
  "query": {
    "term": {
      "字段名": {
        "value": "搜索条件"
      }
    }
  }
}

 实例,查询一个品牌为诺基亚的商品

GET /items/_search
{
  "query": {
    "term": {
      "brand": {
        "value": "诺基亚"
      }
    }
  }
}

range查询(处于某个字段范围内的文档),语法如下: 

GET /{索引库名}/_search
{
  "query": {
    "range": {
      "字段名": {
        "gte": {最小值},
        "lte": {最大值}
      }
    }
  }
}

 实例,查询价格处于500-1000的商品(由于数据库的存储单位为分,所以我们查询时多加两个零):

GET /items/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 50000,
        "lte": 100000
      }
    }
  }
}

range是范围查询,对于范围筛选的关键字有:

  • gte:大于等于

  • gt:大于

  • lte:小于等于

  • lt:小于

复合查询

算分函数查询

采用的相关性打分算法是BM25算法,公式如下:

基本语法

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)基于运算模式做运算,得到最终结果,作为相关性算分。

因此,其中的关键点是:

  • 过滤条件:决定哪些文档的算分被修改

  • 算分函数:决定函数算分的算法

  • 运算模式:决定最终算分结果

实例,给IPhone这个品牌的手机算分提高十倍,分析如下:

  • 过滤条件:品牌必须为IPhone

  • 算分函数:常量weight,值为10

  • 算分模式:相乘multiply

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

bool查询

bool查询,即布尔查询。就是利用逻辑运算来组合一个或多个查询子句的组合。bool查询支持的逻辑运算有:

  • must:必须匹配每个子查询,类似“与”

  • should:选择性匹配子查询,类似“或”

  • must_not:必须不匹配,不参与算分,类似“非”

  • filter:必须匹配,不参与算分

bool查询基本语法:

GET /items/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"name": "手机"}}
      ],
      "should": [
        {"term": {"brand": { "value": "vivo" }}},
        {"term": {"brand": { "value": "小米" }}}
      ],
      "must_not": [
        {"range": {"price": {"gte": 2500}}}
      ],
      "filter": [
        {"range": {"price": {"lte": 1000}}}
      ]
    }
  }
}

出于性能考虑,与搜索关键字无关的查询尽量采用must_not或filter逻辑运算,避免参与相关性算分

 我们要搜索手机,但品牌必须是华为,价格必须是900~1599,那么可以这样写:

GET /items/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"name": "手机"}}
      ],
      "filter": [
        {"term": {"brand": { "value": "华为" }}},
        {"range": {"price": {"gte": 90000, "lt": 159900}}}
      ]
    }
  }
}

排序

elasticsearch默认是根据相关度算分(_score)来排序,但是也支持自定义方式对搜索结果排序。不过分词字段无法排序,能参与排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。

详细说明可以参考官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/sort-search-results.html

 语法如下:

GET /indexName/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "排序字段": {
        "order": "排序方式asc和desc"
      }
    }
  ]
}

实例,按照商品价格进行排序

GET /items/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}

可以看到商品价格呈现降序 

分页

elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。

基础分页

elasticsearch中通过修改fromsize参数来控制要返回的分页结果:

  • from:从第几个文档开始

  • size:总共查询几个文档

类似于mysql中的limit ?, ?

官方文档如下:

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/paginate-search-results.html

基本语法:

GET /items/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0, // 分页开始的位置,默认为0
  "size": 10,  // 每页文档数量,默认10
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}
深度分页

针对深度分页,elasticsearch提供了两种解决方案:

  • search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。

  • scroll:原理将排序后的文档id形成快照,保存下来,基于快照做分页。官方已经不推荐使用。

详情见文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/paginate-search-results.html

总结:

大多数情况下,我们采用普通分页就可以了。查看百度、京东等网站,会发现其分页都有限制。例如百度最多支持77页,每页不足20条。京东最多100页,每页最多60条。

因此,一般我们采用限制分页深度的方式即可,无需实现深度分页。

 高亮

  • 高亮词条都被加了<em>标签

  • <em>标签都添加了红色样式

高亮标签肯定是由服务端提供数据的时候已经加上的

基本语法如下:

GET /{索引库名}/_search
{
  "query": {
    "match": {
      "搜索字段": "搜索关键字"
    }
  },
  "highlight": {
    "fields": {
      "高亮字段名称": {
        "pre_tags": "<em>",
        "post_tags": "</em>"
      }
    }
  }
}

 注意

  • 搜索必须有查询条件,而且是全文检索类型的查询条件,例如match

  • 参与高亮的字段必须是text类型的字段

  • 默认情况下参与高亮的字段要与搜索字段一致,除非添加:required_field_match=false

实例,我们将华为二字高亮显示

GET /items/_search
{
  "query": {
    "match": {
      "name": "华为"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "pre_tags": "<em>",
        "post_tags": "</em>"
      }
    }
  }
}

总结:

查询的DSL是一个大的JSON对象,包含下列属性:

  • query:查询条件

  • fromsize:分页条件

  • sort:排序条件

  • highlight:高亮条件

数据聚合

Bucket聚合

其实就是以分类(category)字段对数据分组。category值一样的放在同一组,属于Bucket聚合中的Term聚合。

基本语法如下:

GET /items/_search
{
  "size": 0, 
  "aggs": {
    "category_agg": {
      "terms": {
        "field": "category",
        "size": 20
      }
    }
  }
}

语法说明:

  • size:设置size为0,就是每页查0条,则结果中就不包含文档,只包含聚合

  • aggs:定义聚合

    • category_agg:聚合名称,自定义,但不能重复

      • terms:聚合的类型,按分类聚合,所以用term

        • field:参与聚合的字段名称

        • size:希望返回的聚合结果的最大数量 

带条件聚合

我们需要从需求中分析出搜索查询的条件和聚合的目标:

  • 搜索查询条件:

    • 价格高于3000

    • 必须是手机

  • 聚合目标:统计的是品牌,肯定是对brand字段做term聚合

语法如下:

GET /items/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "category": "手机"
          }
        },
        {
          "range": {
            "price": {
              "gte": 300000
            }
          }
        }
      ]
    }
  }, 
  "size": 0, 
  "aggs": {
    "brand_agg": {
      "terms": {
        "field": "brand",
        "size": 20
      }
    }
  }
}

Metric聚合

语法如下:

GET /items/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "category": "手机"
          }
        },
        {
          "range": {
            "price": {
              "gte": 300000
            }
          }
        }
      ]
    }
  }, 
  "size": 0, 
  "aggs": {
    "brand_agg": {
      "terms": {
        "field": "brand",
        "size": 20
      },
      "aggs": {
        "stats_meric": {
          "stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

可以看到我们在brand_agg聚合的内部,我们新加了一个aggs参数。这个聚合就是brand_agg的子聚合,会对brand_agg形成的每个桶中的文档分别统计。

  • stats_meric:聚合名称

    • stats:聚合类型,stats是metric聚合的一种

      • field:聚合字段,这里选择price,统计价格

由于stats是对brand_agg形成的每个品牌桶内文档分别做统计,因此每个品牌都会统计出自己的价格最小、最大、平均值。

总结

aggs代表聚合,与query同级,此时query的作用是?

  • 限定聚合的的文档范围

聚合必须的三要素:

  • 聚合名称

  • 聚合类型

  • 聚合字段

聚合可配置属性有:

  • size:指定聚合结果数量

  • order:指定聚合结果排序方式

  • field:指定聚合字段

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1980384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言程序设计-[4] 算法和程序结构

1、算法 一个程序至少包含两个方面&#xff1a;数据结构和算法&#xff0c;算法就是为解决一个问题而采取的方法和步骤&#xff0c;即对程序操作步骤的描述。 算法有一定的评价标准和表示方法&#xff0c;其中流程图法和N-S结构图法是本章需要介绍的两种方法。 &#xff08;…

校园商铺管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;在线咨询管理&#xff0c;咨询回复管理&#xff0c;交流论坛&#xff0c;系统管理 微信端账号功能包括&a…

LabVIEW工件表面瑕疵识别系统

开发了一种利用LabVIEW和IMAQ Vision视觉工具进行工件表面瑕疵识别的系统。该系统通过图像处理技术识别并分类工件表面的裂纹、划痕等缺陷&#xff0c;从而提升生产线的分拣效率和产品质量。 项目背景 工业生产中&#xff0c;工件表面的缺陷直接影响产品质量和生产效率。传统人…

Web开发-html篇-下

这篇是接着上篇的内容&#xff0c;接着介绍html的其他标签及属性的用法&#xff0c;感兴趣的可以从我的html上篇看起 1. 超链接示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&…

打造干净的Git历史:本地仓库整理操作详解

让你的Git提交如行云流水&#xff1a;本地仓库整理指南 一、背景二、整理上一次提交三、整理多次提交四、注意事项五、总结 一、背景 为什么需要本地仓库整理操作呢&#xff1f; 因为本地仓库提交到远程仓库是无法撤回的&#xff0c;只能是从远端仓库拉取数据到本地&#xff0…

安装ubuntu server24.04系统

0.写在前面 Legacy和UEFI比较legacyUEFI定义基于BIOS的传统引导模式新一代的系统引导模式兼容性较好&#xff0c;支持多数系统主要支持64位系统&#xff0c;对旧版本系统支持较差磁盘分区MBR,最大2.2TB&#xff0c;最多4个主分区GPT&#xff0c;最大16TB&#xff0c;理论上无分…

临床试验设计的干预、受试者和结果指标

临床试验是医学研究中至关重要的一环。通过科学设计和严格实施的临床试验&#xff0c;我们能够系统地评估新药、新疗法以及其他医学干预措施的安全性和有效性。临床试验的设计需考虑多个因素&#xff0c;其中干预、受试者和结局是三大关键要素。本文将详细探讨这些要素在临床试…

基于Jeecgboot3.6.3的vue3版本的流程中仿钉钉流程的鼠标拖动功能支持

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为原先仿钉钉流程里不能进行鼠标拖动来查看流程&#xff0c;所以根据作者提供的信息进行修改&#xff0c;在hooks下增加下面文件useDraggableScroll.ts import { ref, onMounted, on…

【Python】操作数据库

一、数据库编程接口 为了对数据库进行统一的操作&#xff0c;大多数语言都提供了标准化的数据库接口&#xff08;API&#xff09;。数据库提供了接口&#xff0c;Python定义了规范&#xff08;包括数据操作的对象、函数等&#xff09;&#xff0c;通过Python定义的对象就能直接…

对称加密 和 非对称加密

对称加密 和 非对称加密 文章目录 对称加密 和 非对称加密对称解密——异或运算非对称解密——RSA算法问题RSA算法社会地位缺点 PS&#xff1a;RSA算法的攻击方式 如果对你有帮助&#xff0c;就点赞收藏把&#xff01;(&#xff61;&#xff65;ω&#xff65;&#xff61;)&am…

支持10K长视频理解的多模态大模型MovieChat(CVPR 2024)

MovieChat: From Dense Token to Sparse Memory for Long Video Understanding 论文信息 paper&#xff1a;CVPR 2024 code&#xff1a;https://rese1f.github.io/MovieChat/ 视觉模型大语言模型&#xff1a;首个支持10K帧长视频理解任务的新型框架&#xff08;推荐这篇公众号…

小程序开发全攻略:从零到上线的实战历程

引言 在当今的数字化时代&#xff0c;小程序凭借其轻便、快捷的特点&#xff0c;成为了连接用户与服务的桥梁。作为一名开发者&#xff0c;你可能正考虑踏入小程序开发的领域&#xff0c;但面对纷繁复杂的开发流程和技术要点&#xff0c;或许会感到无从下手。今天&#xff0c;我…

C 语言文件操作详解

目录 引言 一、基本概念 1.什么是文件 2.文件的属性 3.为什么使用文件 4.二进制文件和文本文件 二、文件的打开和关闭 1.流和标准流 2.文件指针 3.文件的打开和关闭 三、⽂件的顺序读写 1.顺序读写函数 2.详细介绍 1.fgetc 2.fputc 3.fgets 4.fputs 5.fscan…

统计:多变量时间序列分析 — VMA、VAR、VARMA

统计&#xff1a;多变量时间序列分析 — VMA、VAR、VARMA 一、说明 多变量时间序列是一个在大学课堂上经常被忽视的话题。然而&#xff0c;真实世界的数据通常具有多个维度&#xff0c;我们需要多变量时间序列分析技术。在这篇博客中&#xff0c;我们将通过可视化和 Python 实现…

【GLM-4开发实战】Function Call进阶实战:外部函数调用回顾

系列篇章&#x1f4a5; No.文章1【GLM-4开发实战】Function Call进阶实战&#xff1a;外部函数调用回顾2【GLM-4开发实战】Function Call进阶实战&#xff1a;常见挑战之意图识别处理3【GLM-4开发实战】Function Call进阶实战&#xff1a;常见挑战之海量函数处理4【GLM-4开发实…

【STM32】GPIO和AFIO标准库使用框架

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 GPIO简介 GPIO时钟使能 GPIO初始化 工作模式 选择引脚 输出速度 函数应用 GPIO初始化框架 8个电平读写函数 写端口电平 读端口电平 GPIO框架汇总 AFIO简介 AFIO时钟使能 函数应…

【Material-UI】深入理解useAutocomplete Hook:自定义与高级用法

文章目录 一、什么是useAutocomplete&#xff1f;导入useAutocomplete 二、基本用法代码解析 三、高级定制1. 自定义选项渲染2. 分组和排序3. 自定义输入框行为4. 与其他组件集成 四、注意事项1. 类型安全2. 性能优化 五、总结 Material-UI提供了强大的Autocomplete组件&#x…

Stable Diffusion绘画 | 图生图-基础使用介绍—重绘幅度与缩放模式

重绘幅度 重绘幅度越大&#xff0c;出图与原图差异越大。 重绘幅度0.7 重绘幅度0.3 缩放模式 目前有以下四种缩放模式&#xff1a; 原图的宽高是1080x1440&#xff0c;当修改宽高&#xff0c;与原图不一致时&#xff0c;可选择其中一种缩放模式来处理图片。 仅调整大小 缩放…

C++入门基础(上篇)

C入门基础&#xff08;上篇&#xff09; hello everybody!经历了C语言和初阶数据结构的头脑风暴&#xff0c;相信大家对于编程的学习更加开心&#xff0c;所以说接下来我们将迎来C的学习与探索&#xff0c;话不多说让我们开始吧 namespace的价值 在C/C中&#xff0c;变量、函…

计算机毕业设计选题推荐-自习室座位预约系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…