Elasticsearch

50 阅读14分钟

Elasticsearch的基本概念

Elasticsearch的官方文档:www.elastic.co/guide/index…

Elasticsearch是一个开源的分布式搜索和分析引擎,用于实时搜索、分析和存储大规模的数据。它是基于Apache Lucene库搭建的,提供了一个基于RESTful API的分布式搜索平台。

  • 索引:索引是一个逻辑上的数据分组,类似于MySQL中的数据库。索引用于存储和组织具有相似特征的文档。
  • 类型:类型是在在索引中对文档进行逻辑分类的方式,类似于MySQL中的表,在早期版本的Elasticsearch中,一个索引可以包含多个类型,但是从Elasticsearch7.0之后,类型被启用,一个索引只能包含一个默认类型 “_doc”。
  • 文档:文档是Elasticsearch存储、索引和搜索的基本单位,类似于MySQL中的记录,使用JSON格式来表示数据。文档可以是任意结构的数据,类似于惯性数据库中的行数据。
  • 字段:字段是文档中表示数据的具体信息单元,类似于MySQL中的字段,一个文档可以包含多个字段,每个字段具有自己的名称和值。
  • 映射:映射是定义索引中每个字段的数据类型和属性的过程,类似于MySQL中的表结构,映射告诉Elasticsearch如何解析和处理文档中的字段。
  • 倒排索引:倒排索引是一种数据结构,将每个出现在所有文档中单词,以及与之相关的文档信息,建立一个映射关系,用于支持快速的全文搜索。
  • 分词:将文本数据分割成若干个有意义的词元的过程。在索引和搜索过程中,文本数据通过分词器(Analyzer)进行分词操作,将文本转换为可被搜索和匹配的独立单元。
  • 倒排索引:倒排列表记录了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。

    ES内置的分词器:

    • Standard Analyzer:默认的分词器,它对文本进行基本的分词操作,按照空格和标点符号进行分隔,并进行小写化和去除停用词等处理。
    • Simple Analyzer:简单分词器,按照非字母字符进行切分,将文本转换为小写字母。
    • Whitespace Analyzer:空格分词器,按照空格字符进行切分。
    • Keyword Analyzer:关键字分词器,将整个输入作为单一的词元,不进行分词。

    ES所有内置的分词器都不支持中文语法分词,我们一般都选择开源的IK分词器。

Elasticsearch的下载安装

Elasticsearch的配置文件路径:/usr/share/elasticsearch/config/elasticsearch.yml

Kibana的配置文件路径:/usr/share/kibana/config/kibana.yml

Windows-软件包下载安装

Elasticsearch官网:www.elastic.co/cn/elastic-…

Elasticsearch下载地址:www.elastic.co/cn/download…

Kibana下载地址:www.elastic.co/cn/download…

安装 elasticsearch

  1. 解压后双击elasticsearch安装目录下的/bin/elasticsearch.bat
  2. 运行elasticsearch需要先安装jdk并且配置好环境变量

安装kibana

  1. 解压后双击 elasticsearch 安装目录下的/bin/kibana.bat
  2. 运行kibana需要先安装elasticsearch

Windows-Docker下载安装

安装Elasticsearch

  1. 安装es前需要先安装jdk,并且配置jdk环境变量
  2. 拉取elasticsearch镜像:docker pull elasticsearch:7.12.1
  3. 创建共享网络:docker network create es-net
  4. 创建挂载目录
C:\Users\admin\elasticsearch\data
C:\Users\admin\elasticsearch\plugins
C:\Users\admin\elasticsearch\temp
  1. 创建es容器并运行容器
docker run -d --name es -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" -e "discovery.type=single-node" -v C:\Users\admin\elasticsearch\data:/usr/share/elasticsearch/data -v C:\Users\admin\elasticsearch\plugins:/usr/share/elasticsearch/plugins -v C:\Users\admin\elasticsearch\temp:/usr/temp --privileged --network es-net -p 9200:9200 -p 9300:9300 elasticsearch:7.12.1


# 命令解释:
# -name elasticsearch:给容器器名称
# -p 9200:9200:可以通过宿主机的9200端口访问Elasticsearch服务。
# -p 9300:9300:9300端口用于Elasticsearch集群的节点间通信。
# -e "discovery.type=single-node":单点运行
# -e ES_JAVA_OPTS="-Xms250m -Xmx512m":设置初始内存和最大内存,否则可能导致启动不了ES
# --privileged:以最大权限运行容器
# --network es-net:执行容器运行网络,与kibana运行保持在同一网络
  1. 验证es安装成功:浏览器访问 http://localhost:9200

安装kibana

  1. 安装kibana前需要先安装elasticsearch
  2. 拉取kibana镜像:docker pull kibana:7.12.1
  3. 创建kibana容器并运行容器
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://es:9200 --network es-net -p 5601:5601 -d kibana:7.12.1

# 命令解释
# --name kibana:给容器起一个名称
# -e ELASTICSEARCH_HOSTS=http://es:9200:设置环境变量 ELASTICSEARCH_HOSTS 的值为 “http://es:9200”。这表示 Kibana 会连接到这个地址上运行的 Elasticsearch 实例。
# -p 5601:5601:端口映射配置
# --network=es-net:执行容器运行网络
# -d kibana:7.12.1:使用kibana:7.12.1镜像运行容器。
  1. 验证kibana安装成功:浏览器访问 http://localhost:5601

配置IK分词器

IK分词器的下载地址:github.com/medcl/elast…

IK-7.12.1的下载地址:github.com/infinilabs/…

  1. 将ik文件放到C:\Users\admin\elasticsearch\plugins\ik目录下面
  2. 重启elasticsearch容器:docker restart es
  3. 测试IK分词器
# ik_smart:最少切分
# ik_max_word:最细切分

GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "正在学习Elasticsearch"
}

词典的扩展词与停用词

  1. 编辑IK分词器文件下的/config/IKAnalyzer.cfg.xml,选择指定文件中的词为扩展词或者停用词
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">ext.dic</entry>
         <!--可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords">stopword.dic</entry>
        <!--可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
  1. 在IK分词器文件下的config目录下新建扩展词文件ext.dic,并添加扩展词
文轩
wenxuan
  1. 在IK分词器文件下的config目录下新建停止词文件stopword.dic,并添加停止词
嗯
啊
的
  1. 重启elasticsearch:docker restart elasticsearch

Linux-Docker的下载安装

安装Elasticsearch

  1. 安装es前需要先安装jdk,并且配置jdk环境变量
  2. 拉取elasticsearch镜像:docker pull elasticsearch:7.12.1

    或者提前在官网上下载镜像,上传到服务器然后将镜像导入:docker load -i es.tar

  3. 创建挂载目录
mkdir -p /usr/local/docker/elasticsearch/config
mkdir -p /usr/local/docker/elasticsearch/data
mkdir -p /usr/local/docker/elasticsearch/plugins

# 配置任何远程机器都可以访问
echo "http.host: 0.0.0.0" >> /usr/local/docker/elasticsearch/config/elasticsearch.yml
 
# 保证权限
chmod -R 777 /usr/local/docker/elasticsearch/
  1. 创建es容器并运行容器
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms250m -Xmx512m" \
-v /usr/local/docker/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /usr/local/docker/elasticsearch/data:/usr/share/elasticsearch/data \
-v /usr/local/docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.12.1


# 命令解释:
# -name elasticsearch:给容器器名称
# -p 9200:9200:可以通过宿主机的9200端口访问Elasticsearch服务。
# -p 9300:9300:9300端口用于Elasticsearch集群的节点间通信。
# -e "discovery.type=single-node":单点运行
# -e ES_JAVA_OPTS="-Xms250m -Xmx512m":设置初始内存和最大内存,否则可能导致启动不了ES
# -v /usr/local/docker/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:配置文件映射
# -v /usr/local/docker/elasticsearch/data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录
# -v /usr/local/docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录
  1. 验证es安装成功:浏览器访问 http://localhost:9200

安装kibana

  1. 安装kibana前需要先安装elasticsearch
  2. 拉取kibana镜像:docker pull kibana:7.12.1

    或者提前在官网上下载镜像,上传到服务器然后将镜像导入:docker load -i kibana.tar

  3. 创建kibana容器并运行容器
docker run --name kibana \
-e ELASTICSEARCH_HOSTS=http://localhost:9200 \
-p 5601:5601 \
-d kibana:7.12.1

# 命令解释
# --name kibana:给容器起一个名称
# -e ELASTICSEARCH_HOSTS=http://localhost:9200:设置环境变量 ELASTICSEARCH_HOSTS 的值为 “http://ip:9200”。这表示 Kibana 会连接到这个地址上运行的 Elasticsearch 实例。
# -p 5601:5601:端口映射配置
# -d kibana:7.12.1:使用kibana:7.12.1镜像运行容器。
  1. 验证kibana安装成功:浏览器访问 http://localhost:5601

配置IK分词器

IK分词器的下载地址:github.com/medcl/elast…

  1. 将ik文件放到/usr/local/docker/elasticsearch/plugins目录下面
  2. 重启elasticsearch容器:docker restart es
  3. 测试IK分词器
# ik_smart:最少切分
# ik_max_word:最细切分

GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "正在学习Elasticsearch"
}

词典的扩展词与停用词

  1. 编辑IK分词器文件下的/config/IKAnalyzer.cfg.xml,选择指定文件中的词为扩展词或者停用词
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">ext.dic</entry>
         <!--可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords">stopword.dic</entry>
        <!--可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
  1. /var/lib/docker/volumes/es-plugins/_data/ik/config目录下新建扩展词文件ext.dic,并添加扩展词
文轩
wenxuan
  1. /var/lib/docker/volumes/es-plugins/_data/ik/config目录下新建扩展词文件stopword.dic,并添加停止词
嗯
啊
的
  1. 重启elasticsearch:docker restart elasticsearch

Elasticsearch的基本操作

_cat操作

请求路径请求方式请求描述
/_cat/nodesGET查看所有节点
/_cat/healthGET查看ES健康状况
/_cat/masterGET查看主节点
/_cat/indicesGET查看所有索引

索引操作

ES的索引类似于MySQL的数据库,ES索引的约束如下

约束描述
type字符数据类型
index是否创建索引,默认为true
analyzer使用什么分词器
properties字段的子字段

文档的数据类型

类型描述
text可分割的文本
keyword不可分割的文本(品牌、国家、IP地址)
long长整型
integer整型
short短整型
byte字节
double双精度浮点型
float单精度浮点型
boolean布尔型
date日期
object对象

创建索引

// PUT:表示put请求,创建为put请求

PUT /索引库名称
{
  "mappings": {
    "properties": {
      "字段名":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "字段名2":{
        "type": "keyword",
        "index": "false"
      },
      "字段名3":{
        "properties": {
          "子字段": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

查询索引

GET /索引库名

修改索引

索引库中已存在的Mapping无法修改,只能新增字段

PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type""integer"
    }
  }
}

删除索引

DELETE /索引库名

文档操作

新增文档

POST /索引库名/_doc/文档id
{
    "字段1""值1",
    "字段2""值2",
    "字段3": {
        "子属性1""值3",
        "子属性2""值4"
    }
}

查询文档

GET /{索引库名称}/_doc/{id}

删除文档

DELETE /{索引库名}/_doc/id值

修改文档

全量修改:覆盖原来的文档,并添加新的值
PUT /{索引库名}/_doc/文档id
{
    "字段1""值1",
    "字段2""值2"
}

增量修改:只修改指定id匹配的文档中的部分字段
POST /{索引库名}/_update/文档id
{
    "doc": {
         "字段名""新的值",
    }
}

数据迁移

数据迁移:将source索引指定字段的文档复制到dest索引中。

POST /_reindex
{
    "source": {
        "index": "INDEX_NAME",
        "type": "TYPE_NAME"
    },
    "dest": {
        "index": "INDEX_NAME"
    }
}

Elasticsearch的DSL查询操作

查询所有文档

查询索引下所有文档

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

查询指定字段

GET /INDEX_NAME/_search
{
    "query": {
        "match_all": {}
    },
    "_source": ["FIELD_NAME1", "FIELD_NAME2"]
}

条件匹配查询

  • match:match查询是基于分词进行的全文搜索查询,会将查询内容分词后与字段进行匹配,找出符合条件的文档。它适用于需要对分词后的内容进行模糊匹配的情况。
  • match_phrase:match_phrse查询是一种短语匹配查询,它会将查询内容按照相同的顺序进行匹配。只有字段中存在与查询内容完全相同的连续词组时,才会匹配成功。
  • term:term查询是一种精确匹配查询,不会对查询内容进行分词。它会完全匹配字段中的一个词项,而不是分词后的内容。只有字段中的词项与查询内容完全相同时,才会匹配成功。
  • multi_match:multi_match查询可以对多个字段进行查询,并指定不同的权重以调整字段的重要性。它适用于需要在多个字段中进行全文搜索匹配的情况。
  • bool:bool查询是一种组合查询,可以将多个查询条件进行组合,并通过must、must_not、should等逻辑操作符进行组合查询。它可以实现复杂的查询逻辑,如必须满足条件、不能满足某些条件、可选择满足某些条件等。
  • range:根据值的范围进行查询。ge表示大于,gte表示大于等于,lt表示小于,lte表示小于等于。

match、match_phrse、term的区别:

  • match会将查询值和文档值进行拆分,然后文档中的拆分值等于其中一个拆分值也能查询出来;
  • match_phrase不会对查询值拆分,但是会对文档值拆分,然后文档拆分后的所有值有一个符合查询值即可。
  • term不会对查询值拆分,也不会对文档值拆分,然后需要精准匹配才行。

// match查询
GET /INDEX_NAME/_search
{
    "query": {
        "match": {
            "FIELD_NAME": "FIELD_VALUE"
        }
    }
}

// match_phrse查询
GET /INDEX_NAME/_search
{
    "query": {
        "match_phrse": {
            "FIELD_NAME": "FIELD_VALUE"
        }
    }
}

// term查询
GET /INDEX_NAME/_search
{
    "query": {
        "term": {
            "FIELD_NAME": "FIELD_VALUE"
        }
    }
}

// multi_match查询
GET /INDEX_NAME/_search
{
    "query": {
        "multi_match": {
            "query": "FIELD_VALUE",
                "fields": ["FIELD_NAME1", " FIELD_NAME2"]
            }
    }
}

// bool查询
GET /INDEX_NAME/_search
{
    "query": {
        "bool": {
            "must": [
                {"match": {"FIELD_NAME": "FIELD_VALUE"}}
            ],
            "must_not": [
                {"match": {"FIELD_NAME": "FIELD_VALUE"}}
            ],
            "should": [
                {"match": {"FIELD_NAME": "FIELD_VALUE"}}
            ]
        }
    }
}

// range查询,ge表示大于,gte表示大于等于,lt表示小于,lte表示小于等于。
GET /INDEX_NAME/_search
{
    "query": {
        "range": {
            "FIELD_NAME": {
                "ge": 20 // 
            }
        }
    }
}

排序处理

// keyword、数值、日期类型排序语法
GET /INDEX_NAME/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "fieldName": {
          "order": "asc"  // 排序方式ascdesc
      }
    }
  ]
}

分页处理

GET /INDEX_NAME/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0, // 分页开始的位置,默认为0
  "size": 10 // 期望获取的文档总数
}

SpringBoot整合Elasticsearch

SpringBoot整合Elasticsearch的步骤

添加maven依赖

<properties>
    <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>${elasticsearch.version}</version>
    </dependency>
</dependencies>

配置文件中编写ES的Host和port

wenxuan.es.host=43.139.173.84  
wenxuan.es.port=9200

编写ES配置类

package com.wenxuan.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 文轩
 * @create 2024-01-18 19:06
 */
@Configuration
public class ElasticSearchConfig {

    @Value("${wenxuan.es.host}")
    private String host;

    @Value("${wenxuan.es.port}")
    private Integer port;
    
    public static final RequestOptions COMMON_OPTIONS;  
  
    static {  
        // RequestOptions 类的实例可以用于设置的各种参数,包超时时间、刷新策略、路由等  
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();  
        COMMON_OPTIONS = builder.build();  
    }

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

}

SpringBoot进行索引操作

package com.wenxuan;

import com.wenxuan.config.ElasticSearchConfig;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

/**
 * @author 文轩
 * @create 2024-01-18 19:15
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class SearchApplicationTests {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 创建索引
     */
    @Test
    public void createIndex() throws IOException {
        // 1. 创建Request对象
        CreateIndexRequest request = new CreateIndexRequest("test");
        // request.source("{\"mappings\":{\"properties\":{\"name\":{\"type\":\"keyword\",\"analyzer\":\"ik_smart\"},\"address\":{\"type\":\"text\",\"analyzer\":\"ik_smart\"}}}}", XContentType.JSON);
        // 2. 准备请求参数
        request.source("{\"mappings\":{\"properties\":{\"name\":{\"type\":\"keyword\"},\"address\":{\"type\":\"text\"}}}}", XContentType.JSON);
        // 3. 发送创建索引请求
        client.indices().create(request, ElasticSearchConfig.COMMON_OPTIONS);
    }

    /**
     * 删除索引
     */
    @Test
    public void deleteIndex() throws IOException {
        // 1. 创建Request对象
        DeleteIndexRequest request = new DeleteIndexRequest("test");
        // 2. 发送删除索引请求
        client.indices().delete(request, ElasticSearchConfig.COMMON_OPTIONS);
    }

    /**
     * 判断索引是否存在
     * @throws IOException
     */
    @Test
    public void existIndex() throws IOException {
        // 1. 创建request对象
        GetIndexRequest request = new GetIndexRequest("test");
        // 2. 发送请求
        boolean exists = client.indices().exists(request, ElasticSearchConfig.COMMON_OPTIONS);
        System.out.println("是否存在:" + exists);
    }
}

SpringBoot进行文档操作

package com.wenxuan;

import com.wenxuan.config.ElasticSearchConfig;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

/**
 * @author 文轩
 * @create 2024-01-18 19:15
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class SearchApplicationTests {

    @Autowired
    private RestHighLevelClient client;
    
    /**
     * 新增文档
     */
    @Test
    public void addDocument() throws IOException {
        // 1. 创建request对象
        String id = "1";
        IndexRequest request = new IndexRequest("test").id(id);
        // 2. 准备请求参数
        String json = "{\"name\":\"文轩\",\"address\":\"广东深圳\"}";
        request.source(json, XContentType.JSON);
        // 3. 发送请求
        client.index(request, ElasticSearchConfig.COMMON_OPTIONS);
    }

    /**
     * 根据ID查询文档
     */
    @Test
    public void getDocumentById() throws IOException {
        // 1. 创建request对象
        GetRequest request = new GetRequest("test", "1");
        // 2. 发送请求
        GetResponse response = client.get(request, ElasticSearchConfig.COMMON_OPTIONS);
        // 3. 解析响应结果
        String json = response.getSourceAsString();
        System.out.println(json);
    }

    /**
     * 根据ID修改文档
     */
    @Test
    public void updateDocumentById() throws IOException {
        // 1.准备Request
        UpdateRequest request = new UpdateRequest("test", "1");
        // 2.准备请求参数
        String json = "{\"name\":\"文轩\",\"address\":\"广东广州\"}";
        request.doc(json, XContentType.JSON);
        // 3.发送请求
        client.update(request, ElasticSearchConfig.COMMON_OPTIONS);
    }

    /**
     * 根据ID删除文档
     */
    @Test
    public void deleteDocumentById() throws IOException {
        // 1.准备Request
        DeleteRequest request = new DeleteRequest("test", "1");
        // 2.发送请求
        client.delete(request, ElasticSearchConfig.COMMON_OPTIONS);
    }

}

SpringBoot进行DSL操作

package com.wenxuan;

import com.wenxuan.config.ElasticSearchConfig;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

/**
 * @author 文轩
 * @create 2024-01-18 19:15
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class SearchApplicationTests {

    @Autowired
    private RestHighLevelClient client;
    
    /**
     * DSL查询
     */
    @Test
    public void searchData() throws IOException {
        // 1. 创建检索请求对象
        SearchRequest searchRequest = new SearchRequest();

        // 2. 指定检索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // (1)查询所有数据
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        // (2)match查询
        searchSourceBuilder.query(QueryBuilders.matchQuery("name", "wenxuan"));
        // (3)match_phrase查询
        searchSourceBuilder.query(QueryBuilders.matchPhraseQuery("name", "wenxuan"));
        // (4)term查询
        searchSourceBuilder.query(QueryBuilders.termQuery("name", "wenxuan"));
        // (5)multi_match查询
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("wenxuan", "name", "address"));
        // (5)bool查询
        searchSourceBuilder.query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name", "wenxuan")));
        // (6)range查询
        searchSourceBuilder.query(QueryBuilders.rangeQuery("age").gt(18).lt(30));
        // (7)sort处理
        searchSourceBuilder.sort("age", SortOrder.DESC);
        // (8)limit处理
        searchSourceBuilder.from(0).size(10);

        searchRequest.source(searchSourceBuilder);

        // 3. 发送请求,执行检索
        SearchResponse searchResponse = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
        System.out.println(searchResponse.toString());
    }
}