SpringBoot集成、安装、学习elasticsearch-8.0.0-alpha2 加 kibana-8.0.0-alpha2 加 elasticsearch-analysis-ik

河南循中网络科技有限公司 - 精心创作,详细分解,按照步骤,均可成功!



学习资料

本文章大多数内容,都从【尚硅谷】ElasticSearch教程入门到精通(基于ELK技术栈elasticsearch 7.x+8.x新特性)视频中学习,大力推荐,讲得很好!

elasticsearch与solr的比较

1、当单纯的对已有数据进行搜索时,Solr更快。
在这里插入图片描述
2、当实时建立索引时,Solr会产生io阻塞,查询性能较差,ElasticSearch具有明显的优势。
在这里插入图片描述
3、随着数据量的增加,Solr的搜索效率会变得更低,而ElasticSearch却没有明显的变化。
在这里插入图片描述
4、转变我们的搜索基础设施后从Solr ElasticSearch,我们看见一个即时~ 50x提高搜索性能!
在这里插入图片描述
总结
1、es基本是开箱即用(解压就可以用!) ,非常简单。Solr安装略微复杂一丢丢!
2、Solr 利用Zookeeper进行分布式管理,而Elasticsearch自身带有分布式协调管理功能。
3、Solr 支持更多格式的数据,比如JSON、XML、 CSV ,而Elasticsearch仅支持json文件格式。
4、Solr 官方提供的功能更多,而Elasticsearch本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana友好支撑
5、Solr 查询快,但更新索引时慢(即插入删除慢) ,用于电商等查询多的应用;

ES建立索引快(即查询慢) ,即实时性查询快,用于facebook新浪等搜索。
Solr是传统搜索应用的有力解决方案,但Elasticsearch更适用于新兴的实时搜索应用。
6、Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而Elasticsearch相对开发维护者较少,更新太快,学习使用成本较高。

资源下载链接

​ElasticSearch(华为云镜像)​
kibana(华为云镜像)
elasticsearch-analysis-ik(gitHub)

Windows安装

elasticsearch-8.0.0-alpha2安装

下载链接:https://mirrors.huaweicloud.com/elasticsearch/8.0.0-alpha2/elasticsearch-8.0.0-alpha2-windows-x86_64.zip

解压即用!初次启动一定要记录自动生成的,在cmd命令框中的elastic、kibana_system的密码!!!关掉后将不再提醒!!!

bin 启动文件目录
bin–> elasticsearch.bat 双击启动

config 配置文件目录
config–> log4j2 日志配置文件
config–> jvm.options java虚拟机相关的配置(默认启动占4g内存,内容不够需要自己调整)
-Xms1g
-Xmx1g
config–> elasticsearch.yml elasticsearch 的配置文件! 默认外部访问端口号:9200

启动成功后,访问路径,使用elastic账号进行登录:http://localhost:9200/
在这里插入图片描述

集成IK分词器

下载链接:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v8.0.0

注意:选择下载的版本要与elasticsearch版本对应。

关闭elasticsearch服务,解压即用,在elasticsearch的plugins目录下解压缩,解压缩的时候一定要注意是提取到elasticsearch-analysis-ik-8.0.0,而不是提取到当前位置,随后删除压缩包,并启动elasticsearch服务。
在这里插入图片描述
在这里插入图片描述

kibana-8.0.0-alpha2与nodejs安装

nodejs安装

使用kibana需要先安装node.js
下载链接:node.js下载官网
在这里插入图片描述
1、双击安装包,一直点击下一步。
2、点击change按钮,更换到自己的指定安装位置,点击下一步(不修改默认位置也是可以的 )。
3、一直点击下一步,最后安装成功即可。
cmd中验证安装:

node -v        显示安装的nodejs版本
npm -v        显示安装的npm版本

kibana-8.0.0-alpha2安装

下载链接:https://mirrors.huaweicloud.com/kibana/8.0.0-alpha2/kibana-8.0.0-alpha2-windows-x86_64.zip
kibana解压即用!
bin 启动文件目录
bin–>kibana.bat 双击启动
config 配置文件目录
config–> kibana.yml 【kibana访问Elasticsearch的账号与密码】
elasticsearch.username: “kibana_system”
elasticsearch.password: “密码”

config–> kibana.yml【修改汉化】
i18n.locale: “zh-CN”

启动成功后,访问路径,使用elastic账号进行登录:http://localhost:5601/
部分浏览器可能不兼容,打不开,建议多尝试几款浏览器,博主使用的windows10自带的Microsoft Edge浏览器。
在这里插入图片描述

Linux安装

elasticsearch-8.0.0-alpha2安装

下载链接:https://mirrors.huaweicloud.com/elasticsearch/8.0.0-alpha2/elasticsearch-8.0.0-alpha2-linux-x86_64.tar.gz

cd /usr/local/
mkdir es
cd es

上传elasticsearch-8.0.0-alpha2-linux-x86_64.tar.gz文件到创建的目录下

解压命令,解压后记得删除压缩包

tar -zxf elasticsearch-8.0.0-alpha2-linux-x86_64.tar.gz 

重命名

mv elasticsearch-8.0.0-alpha2/ elasticsearch/

新建ES用户

useradd  elastic

为elastic设置密码,passwd后面写的是账号,密码是等下输入确认的

passwd elastic

将/usr/local/es/elasticsearch文件夹的所有者改为elastic,群组改为elastic,-R表示递归设置所以的子文件夹

chown -R elastic:elastic /usr/local/es/elasticsearch

修改配置文件

cd elasticsearch/config/

JVM配置文件文件为jvm.options,可根据系统具体需求修改-Xms、-Xmx参数
i进入编辑,按Esc退出,输入:wq保存退出

vim jvm.options

集成IK分词器

下载链接:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v8.0.0

注意:选择下载的版本要与elasticsearch版本对应。

将下载的elasticsearch-analysis-ik-8.0.0.zip文件放在/usr/local/es/elasticsearch/plugins目录下

cd /usr/local/es/elasticsearch/plugins

elasticsearch-analysis-ik-8.0.0.zip解压到ik文件,解压后记得删除压缩包,如果提示 unzip: 未找到命令,可以通过 yum install unzip安装相关插件包

unzip -d /usr/local/es/elasticsearch/plugins/ik /usr/local/es/elasticsearch/plugins/elasticsearch-analysis-ik-8.0.0.zip 

启动ES

由于ES不支持root用户启动,需要使用su - elastic切换到刚刚创建的es用户进行操作

su - elastic
cd /usr/local/es/elasticsearch/bin/
./elasticsearch

启动成功后需要记住elastic与kibana_system的账号密码,关掉后将不再提醒!!!
在这里插入图片描述

后台启动

./elasticsearch -d

查看运行状态

ps aux | grep elasticsearch

关闭

kill -9 进程id

查看剩余内存大小

free -m

total:总计物理内存的大小
used:已使用的内存大小
free:可用的内存大小
Shared:多个进程共享的内存总额
Buffers/cached:磁盘缓存的大小

kibana-8.0.0-alpha2与nodejs安装

nodejs安装

使用kibana需要先安装node.js
下载链接:node.js下载官网
在这里插入图片描述
上传至/usr/local/es目录下,解压缩,解压后记得删除压缩包

cd /usr/local/es/
tar -xvf node-v16.18.1-linux-x64.tar.xz 

改名为nodejs

mv node-v16.18.1-linux-x64/ nodejs/

此时的bin文件夹中已经存在node以及npm,如果你进入到对应文件的中执行命令行一点问题都没有,不过不是全局的,所以通过建立软链接的方式将这个设置为全局

ln -s /usr/local/es/nodejs/bin/node /usr/local/bin
ln -s /usr/local/es/nodejs/bin/npm /usr/local/bin

验证是否安装成功

node -v        显示安装的nodejs版本
npm -v        显示安装的npm版本

kibana-8.0.0-alpha2安装

下载链接:https://mirrors.huaweicloud.com/kibana/8.0.0-alpha2/kibana-8.0.0-alpha2-linux-x86_64.tar.gz
上传至/usr/local/es目录下,解压缩,解压后记得删除压缩包

cd /usr/local/es/
tar -zxvf kibana-8.0.0-alpha2-linux-x86_64.tar.gz 

改名为kibana

mv kibana-8.0.0-alpha2/ kibana/

去kibana目录下的config/kibana.yml配置相关参数,kibana访问Elasticsearch的账号与密码,安装elasticsearch时初次启动记录保存的,kibana修改汉化kibana.yml最下方i18n.locale的值修改为"zh-CN"

elasticsearch.username: "kibana_system"
elasticsearch.password: "密码"

i18n.locale: "zh-CN"

外网访问配置,同样在config/kibana.yml中解除注释,修改配置,并在云服务器放行5601端口,如果不配置server.publicBaseUrl,启动kibana时,会出现server.publicBaseUrl 缺失,在生产环境中运行时应配置。某些功能可能运行不正常

server.port: 5601
server.host: "0.0.0.0"
server.publicBaseUrl: "http://localhost:5601/"

启动kibana,kibana 不支持root用户启动,如果要用root用户启动就在后面加 --allow-root ,要么就切换别的用户执行,建议切换至别的角色,比如之前创建的elastic角色

cd /usr/local/es/kibana/bin/
./kibana
./kibana --allow-root

切换至elastic角色后台启动,出现这种,直接按Enter回车即可

su - elastic
cd /usr/local/es/kibana/bin/
nohup ./kibana &

在这里插入图片描述

查看运行状态

ps aux | grep kibana

关闭

kill -9 进程id

访问:http://服务器ip地址:5601/,账号密码是安装elasticsearch时初次启动记录保存的elastic

Elasticsearch学习与实践

基础功能

在Kibana中由此处进入控制台。
在这里插入图片描述

索引操作

查询完成后,Kibana右侧会返回响应结果及请求状态
在这里插入图片描述

ES软件的索引可以类比为MySQL中表的概念,创建一个索引,类似于创建一个表。

ES软件不允许修改索引信息,因为ES数据都是以索引的方式来进行管理的,一旦索引进行了修改,所有数据就得重新进行分配,这样会非常麻烦,所以ES不允许修改索引信息。

创建索引
# 创建索引
# PUT 索引名称(小写)
PUT test_index
判断索引
# 判断索引 HTTP状态码:200成功、404不存在
# HEAD 索引名称
HEAD test_index
查询索引
# 查询索引
# GET 索引名称
GET test_index
查询所有索引
# 查询所有索引
GET _cat/indices
删除索引
# 删除索引
# DELETE 索引名称
DELETE test_index

文档操作(索引数据)

文档是ES软件搜索数据的最小单位,不依赖预先定义的模式,所以可以将文档类比为表的一行JSON类型的数据。我们知道关系型数据库中,要提前定义字段才能使用,在Elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。

创建文档
# 创建文档
# PUT 索引名称/_doc/唯一性标识
PUT test_doc/_doc/1001
{
  "id":1001,
  "name":"zhangsan",
  "age":30
}

# 自动创建唯一性标识
# POST 索引名称/_doc
POST test_doc/_doc
{
  "id":1002,
  "name":"lisi",
  "age":40
}
查询文档
# 查询文档
# GET 索引名称/_doc/文档唯一性标识
GET test_doc/_doc/1001
查询文档中所有的数据
# 查询当前文档中所有的数据
# GET 索引名称/_search
GET test_doc/_search
修改文档
# 修改文档,文档唯一性标识如果存在则修改,不存在则添加
# PUT 索引名称/_doc/文档唯一性标识
PUT test_doc/_doc/1001
{
  "id":1001,
  "name":"zhangsan",
  "age":30,
  "tel":123456
}

# 使用POST进行修改文档时一定要注意,文档唯一性标识是否存在,如果不存在的话,不会依照文档唯一性标识来进行创建,而是自动创建文档唯一性标识
# POST 索引名称/_doc/文档唯一性标识
POST test_doc/_doc/1001
{
  "id":1001,
  "name":"zhangsan",
  "age":30,
  "tel":123456789
}
删除文档
# DELETE 索引名称/_doc/文档唯一性标识
DELETE test_doc/_doc/1001

数据搜索

准备demo数据

PUT test_query
PUT test_query/_bulk
{"index":{"_index":"test_query","_id":"1001"}}
{"id":"1001","name":"zhang san","age":30}
{"index":{"_index":"test_query","_id":"1002"}}
{"id":"1002","name":"li si","age":40}
{"index":{"_index":"test_query","_id":"1003"}}
{"id":"1003","name":"wang wu","age":50}
{"index":{"_index":"test_query","_id":"1004"}}
{"id":"1004","name":"zhangsan","age":30}
{"index":{"_index":"test_query","_id":"1005"}}
{"id":"1005","name":"lisi","age":40}
{"index":{"_index":"test_query","_id":"1006"}}
{"id":"1006","name":"wangwu","age":50}
match分词查询

match是分词查询,ES会将数据分词(关键词)保存

# query查询条件
# match是分词查询,ES会将数据分词(关键词)保存
GET test_query/_search
{
  "query": {
    "match": {
      "name": "zhang li"
    }
  }
}

在这里插入图片描述

term完整关键词查询

term是完整关键词查询,会按照完整的关键词进行查询,由于ES会将数据分词(关键词)保存,所以查询zhang san时,由于是两个关键词,而term是完整关键词查询,则查询无果,查询zhangsan则可返回数据

# query查询条件
# term是完整关键词查询,会按照完整的关键词进行查询,由于ES会将数据分词(关键词)保存,所以查询zhang san时,由于是两个关键词,而term是完整关键词查询,则查询无果,查询zhangsan则可返回数据
GET test_query/_search
{
  "query": {
    "term": {
      "name": {
        "value": "zhangsan"
      }
    }
  }
}
_source对查询结果的字段进行限制

_source对查询结果的字段进行限制,仅返回需要的字段

# _source对查询结果的字段进行限制,仅返回需要的字段
GET test_query/_search
{
  "_source": ["name","age"], 
  "query": {
    "match": {
      "name": "zhang li"
    }
  }
}
组合多个条件查询

组合多个条件查询,类似于MySQL中的or,使用bool下should数组进行多条件查询

# 组合多个条件查询 or
# 使用bool下should数组进行多条件查询
GET test_query/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "zhang"
          }
        },{
          "match": {
            "age": "40"
          }
        }
      ]
    }
  }
}
排序后查询

排序后查询,默认是按照文档唯一标识进行正序,可以使用sort自定义排序

# 排序后查询,默认是按照文档唯一标识进行正序,可以使用sort自定义排序
GET test_query/_search
{
  "query": {
    "match": {
      "name": "zhang li"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}
分页查询

分页查询,from表示从哪开始,size表示每页多少条

# 分页查询,from表示从哪开始,size表示每页多少条
GET test_query/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 2
}
聚合搜索
分组查询

分组查询,aggs聚合规则,ageGroup起的规则名称,terms用关键字关联到一起,size:0则表示没有多余的数据了,仅返回分组信息

# 分组查询,aggs聚合规则,ageGroup起的规则名称,terms用关键字关联到一起,size:0则表示没有多余的数据了,仅返回分组信息
GET test_query/_search
{
  "aggs": {
    "ageGroup": {
      "terms": {
        "field": "age"
      }
    }
  },"size": 0
}
求和

求和,aggs聚合规则,sumAge起的规则名称,sum求和,size:0则表示没有多余的数据了,仅返回求和的信息

# 求和,aggs聚合规则,sumAge起的规则名称,sum求和,size:0则表示没有多余的数据了,仅返回求和的信息
GET test_query/_search
{
  "aggs": {
    "sumAge": {
      "sum": {
        "field": "age"
      }
    }
  },"size": 0
}
求平均值

求平均值,aggs聚合规则,avgAge起的规则名称,avg求平均值,size:0则表示没有多余的数据了,仅返回求平均值的信息

# 求平均值,aggs聚合规则,avgAge起的规则名称,avg求平均值,size:0则表示没有多余的数据了,仅返回求平均值的信息
GET test_query/_search
{
  "aggs": {
    "avgAge": {
      "avg": {
        "field": "age"
      }
    }
  },"size": 0
}
获取前几名

获取前几名,aggs聚合规则,top3起的规则名称,top_hits获取前多少名,sort排序,里面的size表示获取前多少名,外面的size:0则表示没有多余的数据了,仅返回获取前几名的信息

# 获取前几名,aggs聚合规则,top3起的规则名称,top_hits获取前多少名,sort排序,里面的size表示获取前多少名,外面的size:0则表示没有多余的数据了,仅返回获取前几名的信息
GET test_query/_search
{
  "aggs": {
    "top3": {
      "top_hits": {
        "sort": [{
          "age": {"order": "desc"}
        }], 
        "size": 3
      }
    }
  },"size": 0
}

索引模板

# 创建一个索引
PUT test_temp
# 查询索引
GET test_temp

查询结果,默认配置信息
在这里插入图片描述

# 创建一个新的索引,修改默认配置信息
PUT test_temp_1
{
  "settings": {"number_of_shards": 2}
}
# 查询索引
GET test_temp_1

查询结果,默认配置信息被修改了
在这里插入图片描述

我们之前对索引进行了一些配置进行设置,但都是在单个索引上进行设置,在实际开发中,我们可能需要创建不止一个索引,但是每个索引或多或少都有一些共性。比如我们在设计关系型数据库时,一般都会为每个表结构设计一些常用的字段,比如创建时间,更新时间,备注信息等。elasticsearch在创建索引的时候,就引入了模板的概念,你可以先设置一些通用的模板,在创建索引的时候,elasticsearch会根据你创建的模板对索引进行设置。

创建模板

模板例子demo

# 创建模板
# PUT _template/模板名称(模板名称小写)
# index_patterns匹配的模板规则
PUT _template/mytemplate
{
  "index_patterns" : [
    "my*"
  ],
  "settings" : {
    "index" : {
      "number_of_shards" : "1"
    }
  },
  "mappings" : {
    "properties" : {
      "now" : {
        "type" : "date",
        "format" : "yyyy/MM/dd"
      }
    }
  }
}

查看模板
# 查看模板
#GET _template/模板名称
GET _template/mytemplate
使用模板
# 使用模板,必须严格遵守index_patterns匹配模板规则
PUT my_test_temp
删除模板
# 删除模板
# DELETE _template/模板名称
DELETE _template/mytemplate

中文分词

elasticsearch默认分词

我们在使用elasticsearch官方默认的分词插件时会发现,其中对中文的分词效果不佳,经常分词后得到的效果不是我们想要的。

# 数据分析 GET _analyze,analyzer分析器,text:内容
GET _analyze
{
  "analyzer": "chinese",
  "text": ["我是一个学生"]
}

在这里插入图片描述

为了能更好地对中文进行搜索和查询,就需要在elasticsearch中集成好的分词器插件,而IK分词器就是对中文提供支持的插件。

使用IK分词器

IK分词器提供了两个分词算法:
ik_smart:最少切分
ik_max_word:最细粒度划分

# 数据分析 GET _analyze,analyzer分析器,text:内容
GET _analyze
{
  "analyzer": "ik_smart",
  "text": ["我是一个学生"]
}

在这里插入图片描述

# 数据分析 GET _analyze,analyzer分析器,text:内容
GET _analyze
{
  "analyzer": "ik_max_word",
  "text": ["我是一个学生"]
}

在这里插入图片描述

文档评分机制

Lucene和ES的得分机制是一个基于词频和逆文档词频的公式,简称为TF-IDF公式。

公式将查询作为输入,使用不同的手段来确定每一篇文档的得分,将每一个因素最后通过公式综合起来,返回该文档的最终得分。这个综合考量的过程,就是我们希望相关的文档被优先返回的考量过程。在Lucene和ES中这种相关性称为得分。

考虑到查询内容和文档的关系比较复杂,所以公式中需要输入的参数和条件非常的多,但是其中比较重要的其实是两个算法机制。

TF(词频)

Term Frequency:搜索文本中的各个词条(term)在查询文本中出现了多少次,出现的次数越多,就越相关,得分会比较高。

IDF(逆文档频率)

Inverse Document Frequency:搜索文本中的各个词条(term)在整个索引中所有文档中出现了多少次,出现的次数越多,说明越不重要,也就越不相关,得分就比较低。

SpringBoot集成elasticsearch

pom文件

		<!-- elasticsearch -->
        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>8.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>

        <dependency>
            <groupId>jakarta.json</groupId>
            <artifactId>jakarta.json-api</artifactId>
            <version>2.0.1</version>
        </dependency>

yaml配置

# 【elasticSearch】
elasticSearch:
  # 主机名
  hostName: localhost
  # 端口
  port: 9200
  # 用户名
  userName: elastic
  # 密码
  passWord: 密码

配置类

package com.xz.elasticsearch;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticsearchConfig {

    @Value("${elasticSearch.hostName}")
    private String hostName;
    @Value("${elasticSearch.port}")
    private Integer port;
    @Value("${elasticSearch.userName}")
    private String userName;
    @Value("${elasticSearch.passWord}")
    private String passWord;

    /**
     * 创建ES客户端
     * @return
     */
    @Bean
    public ElasticsearchClient getRestClient(){
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, passWord));
        // 创建ES客户端
        RestClient restClient = RestClient.builder(
                new HttpHost(hostName, port)
        ).setHttpClientConfigCallback(
                httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
        ).build();
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        ElasticsearchClient client = new ElasticsearchClient(transport);
        return client;
    }
}

工具类

package com.xz.elasticsearch;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOptions;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * ElasticSearch工具类
 */
@Component
public class ElasticsearchUtil {

    @Resource
    private ElasticsearchConfig elasticsearchConfig;

    /**
     * 保存文档
     * @param indexName 索引名称
     * @param documentId 文档唯一标识id
     * @param documentData 文档内容:实体类对象 或者 JSON
     * @return
     * @throws Exception
     */
    public BulkResponse saveDocument(String indexName, String documentId, Object documentData) throws Exception {
        BulkRequest.Builder builder = new BulkRequest.Builder();
        builder.operations(
                op -> op.index(index -> index
                        .index(indexName)
                        .id(documentId)
                        .document(documentData)
                )
        );
        return elasticsearchConfig.getRestClient().bulk(builder.build());
    }

    /**
     * 修改文档
     * @param indexName 索引名称
     * @param documentId 文档唯一标识id
     * @param doc 修改的内容
     * @return
     * @throws Exception
     */
    public UpdateResponse updDocument(String indexName, String documentId, Map<String,Object> doc) throws Exception {
        return elasticsearchConfig.getRestClient().update(builder -> builder
                .index(indexName)
                .id(documentId)
                .doc(doc), Map.class);
    }

    /**
     * 删除文档
     * @param indexName 索引名称
     * @param documentId 文档唯一标识id
     * @return
     * @throws Exception
     */
    public DeleteResponse deleteDocumentById(String indexName, String documentId) throws Exception {
        return elasticsearchConfig.getRestClient().delete(builder -> builder
                .index(indexName)
                .id(documentId)
        );
    }

    /**
     * 指定索引搜索 - 通过documentId文档唯一标识检索
     * @param indexName 索引名称
     * @param documentId 文档唯一标识id
     * @return
     * @throws Exception
     */
    public GetResponse queryDocumentById(String indexName, String documentId) throws Exception {
        return elasticsearchConfig.getRestClient().get(builder -> builder
                .index(indexName)
                .id(documentId)
                ,JSONObject.class
        );
    }

    /**
     * 指定索引搜索 - 检索整个索引中的文档
     * @param indexName 索引名称
     * @param pageNum 页码
     * @param pageSize 条数
     * @return
     * @throws Exception
     */
    public SearchResponse<JSONObject> queryDocumentAll(String indexName,Integer pageNum,Integer pageSize) throws Exception {
        if(pageNum!=null && pageSize!=null){
            return elasticsearchConfig.getRestClient().search(builder -> builder
                    .index(indexName)
                    .from((pageNum-1) * pageSize)
                    .size(pageSize)
                    ,JSONObject.class
            );
        }else{
            return elasticsearchConfig.getRestClient().search(builder -> builder
                    .index(indexName)
                    ,JSONObject.class
            );
        }
    }

    /**
     * 指定索引搜索 - match单字段分词检索
     * @param indexName 索引名称
     * @param parameterKey 参数名
     * @param parameterValue 参数值
     * @param pageNum 页码
     * @param pageSize 条数
     * @return
     * @throws Exception
     */
    public SearchResponse<JSONObject> queryDocumentByMatch(String indexName,String parameterKey,String parameterValue,Integer pageNum,Integer pageSize) throws Exception {
        if(pageNum!=null && pageSize!=null){
            return elasticsearchConfig.getRestClient().search(builder -> builder
                            .index(indexName)
                            .query(queryBuilder -> queryBuilder
                                    .match(matchQueryBuilder -> matchQueryBuilder
                                            .field(parameterKey)
                                            .query(parameterValue)
                                    )
                            )
                            .from((pageNum-1) * pageSize)
                            .size(pageSize)
                    ,JSONObject.class
            );
        }else{
            return elasticsearchConfig.getRestClient().search(builder -> builder
                            .index(indexName)
                            .query(queryBuilder -> queryBuilder
                                    .match(matchQueryBuilder -> matchQueryBuilder
                                            .field(parameterKey)
                                            .query(parameterValue)
                                    )
                            )
                    ,JSONObject.class
            );
        }
    }
}

仅列举了几项工具,能满足基本需求,有特殊需求的话,参照elasticsearch语法,在工具类中自行创建即可。

bool查询总结

must:与关系,相当于关系型数据库中的 and。

should:或关系,相当于关系型数据库中的 or。

must_not:非关系,相当于关系型数据库中的 not。

filter:过滤条件。

range:条件筛选范围。

gt:大于,相当于关系型数据库中的 >。

gte:大于等于,相当于关系型数据库中的 >=。

lt:小于,相当于关系型数据库中的 <。

lte:小于等于,相当于关系型数据库中的 <=

注意

如果出现condition A & condition B & (condition C || condition D)时,使用must+should可以解决,但需要所有条件都包含在must中,将or的条件放到一个should中,而不是must和should平级当must与should平级时,should会失效

{
    "query":{
        "bool":{
            "must":[
                {
                    "bool":{
                        "should":[
                            {
                                "match":{
                                    "conditionA":{
                                        "query":"A"
                                    }
                                }
                            }
                        ]
                    }
                },
                {
                    "bool":{
                        "should":[
                            {
                                "match":{
                                    "conditionB":{
                                        "query":"B"
                                    }
                                }
                            }
                        ]
                    }
                },
                {
                    "bool":{
                        "should":[
                            {
                                "constant_score":{
                                    "filter":{
                                        "match":{
                                            "conditionC":{
                                                "query":"C"
                                            }
                                        }
                                    }
                                }
                            },
                            {
                                "constant_score":{
                                    "filter":{
                                        "match":{
                                            "conditionD":{
                                                "query":"D"
                                            }
                                        }
                                    }
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值