河南循中网络科技有限公司 - 精心创作,详细分解,按照步骤,均可成功!
学习资料
本文章大多数内容,都从【尚硅谷】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安装
解压即用!初次启动一定要记录自动生成的,在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安装
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"
}
}
}
}
}
]
}
}
]
}
}
}