Elasticsearch的学习

Updated on with 0 views and 0 comments

Elasticsearch的学习

Elasticsearch

ES -- Elasticsearch 介绍

  • 全文检索工具、搜索平台、提供搜索功能的服务系统,致力于解决海量数据的搜索功能,当数据量比较多的时候,如果使用 MySQL 等数据库进行模糊查询,那么数据库的索引会失效,不能达到快速查找的目的,那么采用 es 等搜索平台解决此问题,另外当使用模糊查询的时候,不能够有效的实现分词的效果(把短语、句子、文章进行分词汇),因此此问题的解决采用 ES 等搜索平台实现解决(Solr 等)
  • 内存存储的缺陷 容量不及硬盘

    MySQL like 模糊查找

    增加索引 快速查找

    什么情况下才能用到索引

    在使用他们作为条件的时候 where 关键词后面 用到他们作条件 提高查询速度 性能明显提高 提速10倍 几十倍

    只要用到了 与所以无关的字段 就没有索引的功能

    设置了模糊查询、函数、空值等 索引失去作用

    1.有or必全有索引;
    2.复合索引未用左列字段;
    3.like以%开头;
    4.需要类型转换;
    5.where中索引列有运算;
    6.where中索引列使用了函数;
    7.如果mysql觉得全表扫描更快时(数据少);

    如:uname like '%翼德大能%'

    有其中分别几个就能查出来的 分词查询

    正则表达式 实现也较为复杂

    京东搜索:先分词、在搜索、取并集、有排序

  • 倒排索引 -- Solr 和 ES 都是

    首先从句子或者段落或者文章中分词,然后根据这些词汇创建索引(一个词汇对应一个或者多个地址),最后通过词汇作为搜索关键字,在搜索时先通过索引找到地址,再通过地址找到内容。

    本身有一个分词数据库进行分词查找

    image-20210803100947091

    solr 和 es 都是基于 Lucene 的 原生态的东西 jdbc 和 mybatis 的关系

    分布式、高扩展、高实时的搜索与数据分析引擎

    基于Restful web 接口

    ES 是 Java语言开发的

    Apache 许可条款下开源

  • 应用场景

    搜索:海量数据的查询

    日志数据分析

    实时数据分析

ES -- Elasticsearch 安装

官方地址:https://www.elastic.co/cn/

  • 配置 五项 config/elasticsearch.yml

    集群名字 :cluster.name

    节点名字:node.name

    ip 配置:network.host 类似Redis 改0.0.0.0

    默认端口 9200:http.port

    集群主节点:cluster.initial_master_nodes:["",...]

把当前虚拟机的内存调大 否则ES 启动不起来

  • 系统配置 文件 三个

    修改文件数大小

    etc/security/limits.conf

    #===最大可创建文件数太小=======
    vim /etc/security/limits.conf 
    
    # 在文件末尾中增加下面内容
    bh soft nofile 65536
    bh hard nofile 65536
    

    etc/security/limits.d/20-nproc.conf

    #===========
    vim /etc/security/limits.d/20-nproc.conf
    # 在文件末尾中增加下面内容
    bh soft nofile 65536
    bh hard nofile 65536
    *  hard    nproc     4096
    # 注:* 代表Linux所有用户名称
    

    修改内存大小

    etc/sysctl.conf

    #===最大虚拟内存太小=======
    vim /etc/sysctl.conf
    # 在文件中增加下面内容
    vm.max_map_count=655360
    # 重新加载,输入下面命令:
    sysctl -p
    

    执行 sysctl -p

  • ES 默认不支持 root 用户启动

    创建用户

    useradd bh

    passwd bh

    授权、改变es文件的所有者 bh 组 bh

    chown -R bh:bh elasticsearch/

    切换登录用户

    su bh

    cd bin/

    前端启动方式

    ./elasticsearch

    显示started 启动成功

    image-20210803205628497

  • 端口关闭 或者防火墙释放

    因为启动会退步出来,另起一个远程连接

    释放 9200端口 或者关闭防火墙

    systemctl stop firewalld.service

    浏览器进去 ip:9200 返回信息 安装启动成功

    image-20210803210648032

ES -- Elasticsearch 客户端

Postman 或者 Kibana

官网:https://www.elastic.co/cn/kibana/

和 ES 版本配套

  • 配置 conf/kibana.yml

    server.port:5601

    server.host:"0.0.0.0"

    server.name:"kibana-bh"

    elasticsearch.hosts:["http://localhost:9200"](因为安装同一个虚拟机,所以localhost 即可)

    elasticsearch.requestTimeout:99999(milliseconds)

  • 启动 kibana

    cd bin

    由于不建议 root 用户启动 所以需要加上参数

    ./kibana --allow-root

    释放 防火墙 5601

    systemctl stop firewalld.service

    浏览器进进入 ip"5601 进入即可

    显示连接成功

    Dev Tools -- Console 可以搜索数据

    DashBoard 仪表盘

    ES 是 http 协议

    一套增删改查操作

ES 数据结构的介绍

索引、映射、文档

  • 索引(index)

    存储数据的地方,相当于(MySQL)数据库

  • 映射(mapping)

    定义了每个字段的类型、字段所使用的分词器等,相当于表

  • 文档(document)

    最小数据单元,常以 json 格式显示,相当于一行数据

  • 倒排索引

    由文档中所有不重复词的列表构成,对于其中每个词,对应一个文档 id 列表

  • 类型(type)

    一种type就像一类表。如用户表、角色等。

    在 ES7.x 默认为 type_doc(5.x 多种 type,6.x 一种 type 不确定)

ES 操作索引

使用 Postman 或者 Kibana(Dev Tools)

四种 Restful 请求方式

  • 创建索引:PUT 请求方式

    Postman:ip:9200/索引名称(创建数据库的操作)

    Kibana:put 索引名称

  • 查询索引:GET 请求方式

    Postman:ip:9200/索引名称(查询数据库的操作)

    查询回来的 JSON 串

    ip:9200/_all 查询所有索引 自带 2827 行索引

    Kibana:get 索引名称 get _all

  • 删除索引:DELETE 请求方式

    Postman:ip:9200/索引名称(删除数据库的操作) 返回 acknowledge:true

ES 数据类型

  • 简单数据类型

    字符串:text 会分词 keyword 不会分词

    数值:byte、short、integer、long、float、double

    布尔:boolean

    范围类型:integer_range,float_range,double_range,date_range

    日期:date

  • 复杂数据类型

    数组:[] nested

    对象:{} object

ES 操作映射

  • 直接建立映射/表中添加新的字段

    PUT 请求 ip:9200/索引名称/_mapping

    put 索引+json串

    Kibana 中好写 json 串

    Postman 中 Body-raw-JSON

    {
        "properties":{
            "name":{
               "type":"text"
            },
            "sex":{
                "type":"integer"
            }
        }
    }
    
  • 建索引时候建立映射

    PUT 请求 ip:9200/索引名称

    {
        "mappings":{
            "properties":{
                "name":{
                   "type":"text"
                },
                "sex":{
                    "type":"integer"
                }
            }
    	}
    }
    

注意:映射类似表结构,但是表明没有,整体类型是_doc

ES 操作文档

  • 增加/修改

    POST 方式(PUT也行) ip:9200/索引/_doc/编号

    Postman 字符串转日期操作不了

    {
        "name":"张飞",
        "sex":1,
        "bir":"",
        "address":"昌平"
    }
    

    返回 20x都可以 4xxx客户端 5xx 服务器端

  • 查询

    GET 方式

    查指定:ip:9200/索引/_doc/编号

    查所有:ip:9200/索引/_search

  • 删除

    DELETE 方式

    ip:9200/索引/_doc/编号

ES 的分词器 -- IK 分词器安装 中文分词

ik 分词器、结巴分词器、中科院NLPIR、ansj、哈工大LTP、庖丁解牛

词库 新版本

需要maven ES 内置了 JDK

  • JDK 环境变量配置

    /etc/profile 设置 JAVA_HOME

    vim /etc/profile
    # 在profile文件末尾添加
    #java environment
    export JAVA_HOME=/usr/app/software/es/elasticsearch-7.4.0/jdk
    export PATH=$PATH:${JAVA_HOME}/bin
    
    # 保存退出后,重新加载profile
    source /etc/profile
    
  • maven 环境变量配置

    下载 maven 安装包

    安装 wget

    yum install wget

    wget https://archive.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz

    解压 maven 安装包

    tar -zvxf apache-maven-3.6.0-bin.tar.gz -C software/

    /etc/profile 设置 MAVEN_HOME

    export MAVEN_HOME=/usr/app/software/maven
    export PATH=${MAVEN_HOME}/bin:${PATH} 
    # 保存退出后,重新加载profile
    source /etc/profile
    

    建造本地仓库 resp

    mkdir resp

    配置 settings.xml

    localRepository

    mirror

    profile

  • 安装 ik 分词器

    wget https://github.com/medcl/elasticsearch-analysis-ik/archive/v7.10.0.zip

    yum install zip unzip

    uzip elasticsearch-analysis-ik-7.10.0.zip

    打包之前 分词器版本兼容 es7.4.0 需要修改 pom.xml es 版本

    打包:mvn package

    jar 包移动:移动到 es/plugins下 建立目录 analysis-ik

    mkdir analysis-ik

    cp -R /usr/app/elasticsearch-analysis-ik-7.10.0/target/releases/elasticsearch-analysis-ik-7.10.0.zip ./

    解压 拷贝完成的压缩包

    unzip elasticsearch-analysis-ik-7.10.0.zip

    拷贝词典 复制打包之前解压的 ik/config/.. 到 elasticssearch/config

    ctrl+c 停掉进程 在重启 es 与 kibana

ES 的分词器 -- IK 分词器使用

和哪个字段添加分词 添加分词策略

当插入该字段数据 自动分词的同时 建立索引

查询的时候 用 带了分词的字段作条件 倒排索引

GET 请求:ip:9200/_analyze

细粒度分词 ik_max_word

{
    "analyzer":"ik_max_word",
    "text":"乒乓球明年总冠军"
}

粗粒度分词 ik_smart

分的没那么细

GET 请求查询:ip:9200/索引名/_doc/编号

增加分词策略

增加字段 analyzer

PUT 请求:ip:9200/索引名/_mapping

{
    "properties":{
        "address":{
           "type":"text",
            "analyzer":"ik_max_word"
        },
    }
}

POST 请求 添加数据

ip:9200/索引名/_doc/编号

{
    "name":"张飞",
    "sex":1,
    "address":"北京昌平桃源村"
}

使用分词查询

GET 请求 查询分词效果

ip:9200/索引名/_search

不带分词 term

{
    "query":{
        "term":{
            "address":{
                "value":"北京桃源"
            }
        }
    }
}

带分词 match 先分词 在查询 取并集

{
    "query":{
        "match":{
            "address":"北京桃源"   
        }
    }
}

SpringBoot 整合 Elasticsearch

引入 es 的坐标 三个 高级客户端 普通客户端 和 驱动

<!--引入es的坐标-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.4.0</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.4.0</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.4.0</version>
</dependency>

配置文件

# 自定义的没提示
elasticsearch:
  hostname: 192.168.126.20
  port: 9200

Http-client 爬虫...

初始化客户端

配置文件 注入 Bean

@Configuration
@ConfigurationProperties(prefix="elasticsearch")
public class ElasticSearchConfig {

    private String host;
    private int port;

    @Bean
    public RestHighLevelClient client(){
        return new RestHighLevelClient(RestClient.builder(
                new HttpHost(host,port,"http")
        ));
    }  
  
    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

ES 的 Java 操作

  1. 索引操作

    // 创建索引的操作
    @Test
    public void testCreateIndex() throws Exception {
    
        // 通过高级客户端获取一般客户端
        IndicesClient indices = restHighLevelClient.indices();
    
        // 创建添加索引的请求
        CreateIndexRequest request = new CreateIndexRequest("persons4");
    
    
        // 发送请求 -- 获取响应
        CreateIndexResponse response = indices.create(request, RequestOptions.DEFAULT);
    
        // 根据响应、知道请求是否成功
        System.out.println(response);
    }
    
    // 查询索引
    @Test
    public void queryIndex() throws IOException {
        //1:使用client获取操作索引的对象
        IndicesClient indices = restHighLevelClient.indices();
        //2:获得对象,执行具体的操作
        //2.1 创建获取索引的请求对象,设置索引名称
        GetIndexRequest request = new GetIndexRequest("persons4");
        //2.2 执行查询,获得返回值
        GetIndexResponse response = indices.get(request, RequestOptions.DEFAULT);
        //3:获取结果,遍历
        Map<String, Settings> settings = response.getSettings();
        System.out.println(settings);
    }
    
    // 删除索引
    @Test
    public void testDeleteIndex() throws Exception{
        //1:使用client获取操作索引的对象
        IndicesClient indices = restHighLevelClient.indices();
        //2:获得对象,执行具体的操作
        //2.1 创建获取索引的请求对象,设置索引名称
        DeleteIndexRequest request = new DeleteIndexRequest("persons4");
        //2.2 执行查询,获得返回值
        AcknowledgedResponse response = indices.delete(request, RequestOptions.DEFAULT);
        System.out.println(response.isAcknowledged());
    }
    
    // 判断索引是否存在
    @Test
    public void testIndexExists() throws Exception{
        IndicesClient indices = restHighLevelClient.indices();
        GetIndexRequest request = new GetIndexRequest("persons2");
        boolean response = indices.exists(request,RequestOptions.DEFAULT);
        System.out.println(response);
    }
    
  2. 映射操作

    //创建索引同时创建映射
        @Test
        public void testCreateIndexAndMapping()throws Exception{
            //通过高级客户端获取一般客户端
            IndicesClient indices = highLevelClient.indices();
    
            //创建添加索引的请求
            CreateIndexRequest request = new CreateIndexRequest("persons4");
            String mapping = "{\n" +
                    "    \"properties\": {\n" +
                    "      \"name\":{\n" +
                    "        \"type\":\"text\"\n" +
                    "      },\n" +
                    "      \"age\":{\n" +
                    "        \"type\": \"integer\"\n" +
                    "      }\n" +
                    "    }\n" +
                    "  }";
            request.mapping(mapping, XContentType.JSON);
            //发送请求 -- 获取响应
            CreateIndexResponse response = indices.create(request, RequestOptions.DEFAULT);
    
            //根据响应、知道请求是否成功
            System.out.println(response);
        }
    
  3. 文档操作

    //添加文档数据
    @Test
    public void testAddDoc()throws Exception{
        //准备数据 -- Map
        Map map = new HashMap();
        map.put("name","张飞");
        map.put("age",30);
    
        //请求 -- 添加数据的请求
        IndexRequest request = new IndexRequest("persons4").id("1").source(map);
    
        //执行添加 -- 获取响应
        IndexResponse response = highLevelClient.index(request, RequestOptions.DEFAULT);
    
        //打印响应
        System.out.println(response);
    }
    
    //添加文档数据 -- 采用实体类对象封装数据 -- id存在则实现修改操作   id不存在则实现添加操作
    @Test
    public void testAddDoc2()throws Exception{
        //准备数据 -- Map
        Person person = new Person(2,"关云长",32);
        //转json串
        String json = JSON.toJSONString(person);
    
        //请求 -- 添加数据的请求
        IndexRequest request = new IndexRequest("persons4").id(person.getPid()+"").source(json,XContentType.JSON);
    
        //执行添加 -- 获取响应
        IndexResponse response = highLevelClient.index(request, RequestOptions.DEFAULT);
    
        //打印响应
        System.out.println(response);
    }
    
    //根据id查询数据
    @Test
    public void testGetDocId() throws Exception{
        GetRequest request = new GetRequest("persons4").id("2");
        GetResponse response = highLevelClient.get(request, RequestOptions.DEFAULT);
        //Map<String, Object> map = response.getSourceAsMap();
        //System.out.println(map);
    
        String json = response.getSourceAsString();
        System.out.println(json);
        //json串转回对象
        Person person = JSON.parseObject(json, Person.class);
        System.out.println(person);
    }
    
    //删除数据-- 根据id
    @Test
    public void testDeleteId()throws Exception{
        DeleteRequest request = new DeleteRequest("persons4").id("1");
        DeleteResponse response = highLevelClient.delete(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
    
  4. 高级操作

    ES 的 批量操作 bulk

    //批量操作
    @Test
    public void testBulk()throws Exception{
        //批量操作请求
        BulkRequest bulkRequest = new BulkRequest();
    
        //批量操作添加到请求中
        DeleteRequest deleteRequest = new DeleteRequest("persons4").id("3");
        bulkRequest.add(deleteRequest);
    
    
        Map map = new HashMap();
        map.put("name","刘备");
        map.put("age",33);
        IndexRequest indexRequest = new IndexRequest("persons4").id("2").source(map);
        bulkRequest.add(indexRequest);
    
        Map map2 = new HashMap();
        map2.put("name","曹操");
        map2.put("age",35);
        UpdateRequest updateRequest = new UpdateRequest("persons4","1").doc(map2);
        bulkRequest.add(updateRequest);
    
        //指定批量操作 -- 获取响应
        BulkResponse response = highLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
    
        //打印响应
        System.out.println(response);
    }
    

数据批量添加 ES

列表 ES 详情 MySQL

商家录入商品 保存两个地方 MySQL 和 ES

增加 MP 依赖

字段保存 JSON 串,Map<String,Object>接收,但先排除

@TableField("spec")
private String specStr;
//排除 不能和表中同名字段对应
@TableField(exist = false)
private Map<String,Object>spec;

```java
//从数据库查询数据 -- 把数据库中数据批量导入到es中
@Test
public void  testAll()throws Exception{
    List<Item> list = itemDao.selectList(null);
    BulkRequest request = new BulkRequest();
    for(Item item : list){
        System.out.println(item);

        String specStr = item.getSpecStr();
        Map<String,Object> map = JSON.parseObject(specStr, Map.class);
        item.setSpec(map);

        String json = JSON.toJSONString(item);
        IndexRequest indexRequest = new IndexRequest("items").id(item.getId() + "").source(json, XContentType.JSON);
        request.add(indexRequest);
    }
    BulkResponse response = highLevelClient.bulk(request, RequestOptions.DEFAULT);
    System.out.println(response);
}

ES 的高级操作

//查询所有 -- 默认显示前10条
@Test
public void testSelectAll()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //追加条件 -- 没有条件
    MatchAllQueryBuilder query = QueryBuilders.matchAllQuery();//没有条件

    //把条件添加到构造器
    searchSourceBuilder.query(query);
    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }
}
//带条件查询 -- 显示前20条 -- 不分词
@Test
public void testSelectConTerm()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //追加条件 
    TermQueryBuilder query = QueryBuilders.termQuery("title", "三星小米");

    //把条件添加到构造器
    searchSourceBuilder.query(query);
    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }
}
//带条件查询 -- 显示前20条 -- 分词
@Test
public void testSelectConMatch()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //追加条件 -- 没有条件
    MatchQueryBuilder query = QueryBuilders.matchQuery("title", "三星小米");

    //把条件添加到构造器
    searchSourceBuilder.query(query);
    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }
}
//带条件查询 -- 显示前20条 -- 实现模糊查询
@Test
public void testSelectLike()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //模糊
    WildcardQueryBuilder query = QueryBuilders.wildcardQuery("title", "小*");

    //把条件添加到构造器
    searchSourceBuilder.query(query);
    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }
}
//带条件查询 -- 显示前20条 -- 实现范围查询
@Test
public void testSelectBetween()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //范围查询
    RangeQueryBuilder query = QueryBuilders.rangeQuery("price");
    query.gte(1);
    query.lte(100);

    //把条件添加到构造器
    searchSourceBuilder.query(query);
    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);
    searchSourceBuilder.sort("price", SortOrder.DESC);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }
}
//带条件查询 -- 显示前20条 -- 多条件查询 -- 好几个字段同时查询
@Test
public void testSelectManyCon()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //多条件
    QueryStringQueryBuilder query = QueryBuilders.queryStringQuery("华为小米").field("categoryName").field("brandName").field("title");

    //把条件添加到构造器
    searchSourceBuilder.query(query);
    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);
    searchSourceBuilder.sort("price", SortOrder.DESC);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }
}
//带条件查询 -- 显示前20条 -- 指标聚合 -- 查询最大值
@Test
public void testSelectMax()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //指标聚合 -- 取价格最大值
    MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机");
    //把条件添加到构造器
    searchSourceBuilder.query(query);

    //max_price=299000.00
    MaxAggregationBuilder price = AggregationBuilders.max("max_price").field("price");
    searchSourceBuilder.aggregation(price);

    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);
    searchSourceBuilder.sort("price", SortOrder.DESC);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }

    //获取价格最大值
    Aggregations aggregations = response.getAggregations();
    Map<String, Aggregation> stringAggregationMap = aggregations.asMap();
    Max max = (Max) stringAggregationMap.get("max_price");
    double value1 = max.getValue();
    System.out.println(value1);
}
//带条件查询 -- 显示前20条 -- 桶聚合 -- 分组 -- 使用品牌分组brandName
@Test
public void testSelectGroup()throws Exception{
    //搜索请求
    SearchRequest searchRequest = new SearchRequest("items");

    //条件构造器
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //指标聚合 -- 取价格最大值
    MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机");
    //把条件添加到构造器
    searchSourceBuilder.query(query);

    //使用品牌分组
    TermsAggregationBuilder field = AggregationBuilders.terms("goods_brands").field("brandName");
    searchSourceBuilder.aggregation(field);

    //下标从0开始计数,实现显示
    //searchSourceBuilder.from(10);//816448
    //改变页容量
    searchSourceBuilder.size(20);
    searchSourceBuilder.sort("price", SortOrder.DESC);

    //把构造器添加到搜索请求
    searchRequest.source(searchSourceBuilder);

    //执行查找操作
    SearchResponse response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //获取默认查到的10条数据
    SearchHits hits = response.getHits();
    //总行数
    TotalHits totalHits = hits.getTotalHits();
    long value = totalHits.value;
    System.out.println("总行数:"+value);
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String source = hit.getSourceAsString();
        System.out.println(source);
    }

    //获取分组数据
    Aggregations aggregations = response.getAggregations();
    Map<String, Aggregation> stringAggregationMap = aggregations.asMap();
    Terms terms = (Terms) stringAggregationMap.get("goods_brands");
    List<? extends Terms.Bucket> buckets = terms.getBuckets();
    for(Terms.Bucket bucket : buckets){
        Object key = bucket.getKey();
        System.out.println(key);
    }
}

标题:Elasticsearch的学习
作者:HB2Ocean
地址:http://future-hb.top:8080/articles/2021/08/04/1628006598285.html