06_es分布式搜索引擎2

news2025/1/21 1:01:26

一、DSL查询文档

1.DSL查询分类

①查询所有:match_all

②全文检索:利用分词器对用户输入的内容分词,倒排索引去匹配

    match_query

    multi_match_query

③精确查询:根据精确词条查找数据,查找的是keyword,数值,日期,boolean类型字段

    ids,range,term

④地理geo查询:根据经纬度查询

    geo_distance

    geo_bounding_box

⑤复合查询:将各种条件组合起来,合并查询条件

    bool

    function_score

 总结:查询DSL的基本语法是什么?

GET /索引库名/_search

{ "query": { "查询类型": { "FIELD": "TEXT"}}}

2.全文检索

全文检索查询,会对用户输入内容进行分词。用于搜索框搜索

 ①match查询:对用户输入的内容分词,然后倒排索引库查询。一个字段

查询三钻的酒店

GET /hotel/_search
{
  "query": {
    "match": {
      "starName": "三钻"
    }
  }
}

②multi_match:多个字段查询。参与的字段越多,查询性能越差。

 查询品牌,酒店名,商业圈有“外滩如家”

GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "外滩如家",
      "fields": ["brand","name","business"]
    }
  }
}

3.精确查询

查询的keyword,不进行分词的字段

①term:根据词条准确值查询

②range:范围查询(价格)

 ①term:

查询品牌是“7天酒店”

GET /hotel/_search
{
  "query": {
    "term": {
      "brand": {
        "value": "7天酒店"
      }
    }
  }
}

②range:

查询200-250酒店

GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 200,
        "lte": 250
      }
    }
  }
}

总结:精确查询常见的有哪些?

  • term查询:根据词条精确匹配,一般搜索keyword类型、数值类型、布尔类型、日期类型字段
  • range查询:根据数值范围查询,可以是数值、日期的范围

4.地理查询

场景:

查询附近的酒店,附近的人,打车附近的出租车

 ①矩形范围内:geo_bounding_box

 ②以指定中心点为半径:

 查询这个点15公里范围内的酒店

GET /hotel/_search
{
  "query": {
    "geo_distance":{
      "distance":"15km",
      "location":"31.282444,121.479385"
    }
  }
}

5.相关性算分:竞价排名

①fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名

 

 ②词条频率越高,得分越高,排名越靠前

 

③elasticsearch中的相关性打分算法是什么?

  • TF-IDF:在elasticsearch5.0之前,会随着词频增加而越来越大
  • BM25:在elasticsearch5.0之后,会随着词频增加而增大,但增长曲线会趋于水平

 

 

6.修改相关性算分:竞价排名

使用 function score query,可以修改文档的相关性算分(query score),根据新得到的算分排序。

 

①原始条件查询,搜索文档并根据相关性打分(query score)

②过滤条件:符合条件的文档才重新算分

③算分函数:

算分函数,算分函数的结果称为function score ,将来会与query score运算,得到新算分,常见的算分函数有:

  • weight:给一个常量值,作为函数结果(function score)
  • field_value_factor:用文档中的某个字段值作为函数结果
  • random_score:随机生成一个值,作为函数结果
  • script_score:自定义计算公式,公式结果作为函数结果

④加权模式,定义function score与query score的运算方式,包括:

  • multiply:两者相乘。默认就是这个
  • replace:用function score 替换 query score
  • 其它:sum、avg、max、min

案例:搜索外滩的酒店,“如家”品牌给公司充钱了,让他的排名靠前一些。

分析:

①文档为品牌是“如家”的

②算分函数是weight

③加权模式是求和sum

GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "all": "外滩"
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "brand": "如家"
            }
          },
          "weight": 2
        }
      ],
      "boost_mode": "sum"
    }
  }
}

7.复合查询Boolean Query

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

must:”与”,必须匹配每个子查询

should:“或”选择性匹配子查询

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

filter:必须匹配,不算分。

案例1:查询上海的酒店,品牌是皇冠假日或华美达。价格不低于500,评分是大于45分的

 

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

GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "如家"
          }
        }
      ],
      "must_not": [
        {
          "range": {
            "price": {
              "gte": 400
            }
          }
        }
      ],
      "filter": [
        {
          "geo_distance": {
            "distance": "10km",
            "location": {
              "lat": 31.21,
              "lon": 121.5
            }
          }
        }
      ]
      
    }
  }
}

二、搜索结果处理

1.排序

es支持对搜索结果排序,默认是根据相关度算分(_score)排序。可以排序的字段:keyword类型,数值类型,地理坐标类型,日期类型。

排序语法

 地理坐标排序语法

 案例1:对酒店数据按照用户评价降序排序,评价相同的按照价格升序排序

GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "score":"desc"
    },
    {
      "price": "asc"
    }
  ]
}

案例2:实现对酒店数据按照到你的位置坐标的距离升序排序

获取经纬度的方式:https://lbs.amap.com/demo/jsapi-v2/example/map/click-to-get-lnglat/

GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 31.220393,
          "lon": 121.544427
        },
        "order": "asc",
        "unit": "km"
      }
    }
  ]
}

2.分页

es的搜索结果默认是top10条。

es通过修改from,size参数控制返回的分页结果

 

深度分页问题

ES是分布式的,所以会面临深度分页问题。例如按price排序后,获取from = 990,size =10的数据:

 

①首先在每个数据分片上都排序并查询前1000条文档。

②然后将所有节点的结果聚合,在内存中重新排序选出前1000条文档

③最后从这1000条中,选取从990开始的10条文档

如果搜索页数过深,或者结果集(from + size)越大,对内存和CPU的消耗也越高。因此ES设定结果集查询的上限是10000

总结

from + size:

  • 优点:支持随机翻页
  • 缺点:深度分页问题,默认查询上限(from + size)是10000
  • 场景:百度、京东、谷歌、淘宝这样的随机翻页搜索

after search:

  • 优点:没有查询上限(单次查询的size不超过10000)
  • 缺点:只能向后逐页查询,不支持随机翻页
  • 场景:没有随机翻页需求的搜索,例如手机向下滚动翻页

3.高亮

搜索关键字突出显示。

原理:

①搜索关键字标记出来

②页面加css样式

案例:如家酒店高亮

 

 

三、RestClient查询文档

1.快速入门

①请求DSL的组织

 RestAPI中其中构建DSL是通过HighLevelRestClient中的resource()来实现的,其中包含了查询、排序、分页、高亮等所有功能

 RestAPI中其中构建查询条件的核心部分是由一个名为QueryBuilders的工具类提供的,其中包含了各种查询方法

 ②解析结果response

③查询全部酒店的完整代码

 

@Test
void testMatchAll() throws IOException {
   // 1.准备查询请求,参数是索引库名
   SearchRequest request = new SearchRequest("hotel");
   // 2.组织DSL参数
   request.source().query(QueryBuilders.matchAllQuery());
   // 3.发送请求,得到响应
   SearchResponse response = client.search(request, RequestOptions.DEFAULT);
   // 4.解析结果
   SearchHits searchHits = response.getHits();
   // 4.1 获取查询的条数
   long total = searchHits.getTotalHits().value;
   // 4.2 获取查询的集合
   SearchHit[] hits = searchHits.getHits();
   // 4.3 遍历
   List<HotelDoc>hotelDocList = new ArrayList<>();
   for (SearchHit hit : hits) {
      // 转换为Json
      String json = hit.getSourceAsString();
      // 转换为java对象
      HotelDoc hotelDoc = JSONObject.parseObject(json, HotelDoc.class);
      // 保存在集合中
      hotelDocList.add(hotelDoc);
   }
   System.out.println(hotelDocList);
}

查询的基本步骤是:

  • 创建SearchRequest对象
  • 准备Request.source(),也就是DSL。
    • QueryBuilders来构建查询条件
    • 传入Request.source() 的 query() 方法
  • 发送请求,得到结果
  • 解析结果(参考JSON结果,从外到内,逐层解析)

2.构建查询条件,只要记住一个类:QueryBuilders

①全文检索查询(分词,模糊查询)

单字段:QueryBuilders.matchQuery(字段名,值)

多字段:QueryBuilders.multiMatchQuery(值, 字段1,字段2);

演示:酒店名字带有“如家“的有哪些?

request.source().query(QueryBuilders.termQuery("name","如家"));

②精确查询,不分词

精确查询常见的有term查询和range查询

③复合查询boolean query

查询品牌为如家,价格在200元内的酒店

// 创建bool查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 添加must条件
boolQuery.must(QueryBuilders.termQuery("brand","如家"));
// 添加filter条件
boolQuery.filter(QueryBuilders.rangeQuery("price").lte(200));
request.source().query(boolQuery);

3.分页和排序

 演示:查询名为“如家“的酒店,查询结果进行价格降序,每页显示3条

// 页码
int page = 1,size=3;
// 2.组织DSL
// 2.1 查询
request.source().query(QueryBuilders.termQuery("name","如家"));
// 2.2 分页 从from序号数size个
request.source().from((page-1)*size).size(size);
// 2.3 价格排序
request.source().sort("price", SortOrder.DESC);

4.高亮

根据name搜索高亮

 代码

@Test
void testHight() throws IOException{
   // 1.请求request
   SearchRequest request = new SearchRequest("hotel");
   // 2. 组织DSL
   request.source().query(QueryBuilders.matchQuery("all","如家"));
   request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
   // 3.发送请求,得到响应
   SearchResponse response = client.search(request, RequestOptions.DEFAULT);
   // 4.分析结果
   SearchHits searchHits = response.getHits();
   // 5.解析
   SearchHit[] hitss = searchHits.getHits();
   // 6.遍历
   for (SearchHit hit : hitss) {
      // 转换为json
      String json = hit.getSourceAsString();
      // 得到对象
      HotelDoc hotelDoc = JSONObject.parseObject(json, HotelDoc.class);
      // 获取高亮结果
      Map<String, HighlightField> highlightFields = hit.getHighlightFields();
      // 根据字段获取
      HighlightField highlightField = highlightFields.get("name");
      // 获取高亮值
       String name = highlightField.getFragments()[0].string();
       // 覆盖结果
      hotelDoc.setName(name);
      System.out.println(name);

   }

}

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

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

相关文章

BUCK、BOOST、BUCK-BOOST电路原理分析

一、前导 DC-DC DC-DC电源&#xff0c;即直流-直流变换器&#xff0c;是指将一个固定的直流电压变换为可变的直流电压&#xff0c;也称为直流斩波器。DC-DC有多种拓扑结构&#xff0c;如BUCK&#xff08;降压&#xff09;、BOOST&#xff08;升压&#xff09;、BUCK-BOOST&…

基于EPICS stream模块的直流电源的IOC控制程序实例

本实例程序实现了对优利德UDP6720系列直流电源的网络控制和访问&#xff0c;先在此介绍这个项目中使用的硬件&#xff1a; 1、UDP6721直流电源&#xff1a;受控设备 2、moxa串口服务器5150&#xff1a;将UDP6721直流电源设备串口连接转成网络连接 3、香橙派Zero3&#xff1a;运…

绿色通道 快速理赔,渤海财险用实干书写服务品牌

7月底&#xff0c;受台风“杜苏芮”影响&#xff0c;北京市连续强降雨&#xff0c;西部、西南部、南部遭遇特大暴雨&#xff0c;房山、门头沟、丰台等地陆续出现山洪暴发现象。      灾害无情人有情&#xff0c;为更好地保障人民群众生命财产安全&#xff0c;渤海财险北京分…

【PWN · 栈迁移|off-by-one|伪随机|爆破】[HDCTF 2023]Makewish

一道精巧、包含很多要点的题目 一、题目 二、思路浅析 通过ctypes酷通过伪随机数检测&#xff0c;没用srand指定随机种子时&#xff0c;默认srand(1)。 通过puts_name的off-by-one来泄露canary 进入vuln时&#xff0c;发现只能刚好填充到rbp前面&#xff0c;但是会将最后一个…

虚拟机设置linux系统固定网络IP

文章目录 虚拟机设置linux系统固定网络IP1.设置虚拟机网络ip2.windows网络适配器设置1.windows112.其他windows版本 3.linux系统IP设置 虚拟机设置linux系统固定网络IP 1.设置虚拟机网络ip 2.windows网络适配器设置 1.windows11 2.其他windows版本 后面设置内容参考windows11…

基于OrangePi Zero 2实现垃圾分类智能垃圾桶项目(11)将指令来源和次数保存到数据库中(SQLite),指令来源和发出时间以及垃圾类型保存在文件中

SQLite&#xff08;嵌入式数据库&#xff09; 概念&#xff1a; 一种轻量级的关系型数据库管理系统&#xff0c;可以在应用程序中作为一个单独的组件运行&#xff0c;因此也被称为嵌入式数据库。与传统的客户端-服务器架构不同&#xff0c;SQLite 数据库存储在单个文件中&…

虹科案例 | AR内窥镜手术应用为手术节约45分钟?

相信医疗从业者都知道&#xff0c;在手术室中有非常多的医疗器械屏幕&#xff0c;特别是内窥镜手术室中医生依赖这些内窥镜画面来帮助病患进行手术。但手术室空间有限&#xff0c;屏幕缩放位置相对固定&#xff0c;在特殊场景下医生观看内窥镜画面时无法关注到病患的状态。这存…

axios 实现请求 loading 效果

前景提要&#xff1a; ts 简易封装 axios&#xff0c;统一 API 实现在 config 中配置开关拦截器 loading 分为全屏 loading 和局部 loading。 axios 中设置 loading 只能设置全屏 loading&#xff0c;因为局部 loading 需要当前局部的 dom&#xff0c;在 axios 中显然拿不到发…

数据结构:排序干货!(7大排序汇总+快速排序的优化+计数排序+基数排序+桶排序)

目录 概念 插入排序 直接插入排序 希尔排序 选择排序 直接选择排序 双向选择排序 堆排序 交换排序 冒泡排序 快速排序 Hoare法 挖坑法 前后指针法 快排的优化 三数取中法 非递归快排 归并排序 分治算法二路归并 非递归归并 应用 排序总结 其他排序 计数…

记一次有趣的免杀探索

文章目录 前记查杀排查源码修改免杀效果测试 前记 evilhiding昨天被提issue不能绕过火绒了&#xff0c;于是今天更新了evilhiding v1.1&#xff0c;已经可以继续免杀了。 期待各位的stars&#xff0c;项目地址如下&#xff1a; https://github.com/coleak2021/evilhiding查杀…

【OJ比赛日历】快周末了,不来一场比赛吗? #11.04-11.10 #10场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-11-04&#xff08;周六&#xff09; #2场比赛2023-11-05…

科技云报道:大模型会给操作系统带来什么样的想象?

科技云报道原创。 在人工智能的发展历程中&#xff0c;大模型的出现标志着一个里程碑。 特别是近年来&#xff0c;诸如GPT-4、BERT等大模型的出现&#xff0c;不仅在自然语言处理、图像识别等领域取得了令人瞩目的成就&#xff0c;还推动了人工智能技术向更广泛的应用场景拓展…

IAR更新内置JLink

一、背景 IAR8.32,基于GD32F303CET6的工程&#xff0c;能正常使用JLINK进行debug and download&#xff0c;但在调试GD32F303CGT6时程序无法正常download且校验失败 GD32F303CET6&#xff1a;Flash--512K,RAM--64K GD32F303CET6&#xff1a;Flash--1M,RAM--96K 二、原因分析…

GZ035 5G组网与运维赛题第10套

2023年全国职业院校技能大赛 GZ035 5G组网与运维赛项&#xff08;高职组&#xff09; 赛题第10套 一、竞赛须知 1.竞赛内容分布 竞赛模块1--5G公共网络规划部署与开通&#xff08;35分&#xff09; 子任务1&#xff1a;5G公共网络部署与调试&#xff08;15分&#xff09; 子…

开关电源综合电气试验项目是什么?常规电源测试的标准和规范有哪些?

开关电源综合电气试验内容 1. 绝缘电阻和抗电强度测试 2. 输入浪涌电流测试 3. 输出电压、输入功率、输入功率因素、工作效率测试 4. 输出电压纹波及噪声测试 5. 输出过流保护测试 6. 短路保护测试 7. 输出电压过压保护测试 8. 过冲幅度及暂态恢复时间测试 9. 开机启动时间及关…

3dMax章鱼插件Octopus

3dMax章鱼插件Octopus 3dMax章鱼插件&#xff0c;不仅在视口中以饼状的形式&#xff0c;呼出各种属性参数&#xff0c;方便调用&#xff0c;而且是一个可编写脚本的框架&#xff0c;因此您有很多机会创建自己的菜单并轻松分发。整个OCTOPUS系统可以使用maxscript进行自定义&…

Linux shell编程学习笔记20:case ... esac、continue 和break语句

一、case ... esac语句说明 在实际编程中&#xff0c;我们有时会请到多条件多分支选择的情况&#xff0c;用if…else语句来嵌套处理不烦琐&#xff0c;于是JavaScript等语言提供了多选择语句switch ... case。与此类似&#xff0c;Linux Shell脚本编程中提供了case...in...esa…

睿趣科技:想知道开抖音小店的成本

随着互联网的发展&#xff0c;越来越多的人开始尝试通过开设网店来创业。抖音作为目前最受欢迎的短视频平台之一&#xff0c;也提供了开店的功能。那么&#xff0c;开一家抖音小店需要多少成本呢&#xff1f; 首先&#xff0c;我们需要了解的是&#xff0c;抖音小店的开店费用是…

Git 指令白雪警告!在IDEA中配置使用Git管理提交代码,无需繁杂指令

目录 1. 前言 2. Git 路径配置步骤 3. IDEA中使用Git管理项目 3.1 第一种做法 3.2 第二种做法 4. IDEA中提交代码和推送代码 5. 分支相关操作 5.1 创建分支 5.2 切换分支&#xff0c;删除分支 6. 拉取更新代码并处理分支冲突 1. 前言 相信有很多小伙伴在学习 Git 指…

libuv进程通信与管道描述符

libuv 提供了大量的子进程管理&#xff0c;抽象了平台差异并允许使用流或命名管道与子进程进行通信。Unix 中的一个常见习惯是每个进程只做一件事&#xff0c;并且把它做好。在这种情况下&#xff0c;一个进程通常会使用多个子进程来完成任务&#xff08;类似于在 shell 中使用…