赞
踩
搜索原理概括:
索引就类似于目录,平时使用的索引都是通过主键定位到数据,倒排索引刚好相反,就是通过数据定位到主键
id | name | content |
1 | lin01 | 内容1 |
2 | lin02 | 内容2 |
3 | lin01 | 内容3 |
4 | lin某某 | 内容2 |
通过id可以查询到name/content
关键词 | id |
lin01 | 1,3 |
内容2 | 2,4 |
把name与content的字段抽取关键词。通过这个关键词搜索的时候,那么这个关键词就有可能出现在name/content字段内容中。
Elasticsearch 与 Mysql 对比:
ES 里的 Index 可以看做一个库,而 Types 相当于表, Documents 则相当于表的行。这里 Types 的概念已经被逐渐弱化, Elasticsearch 6.X 中,一个 index 下已经只能包含一个type, Elasticsearch 7.X 中, Type 的概念已经被删除了。
ElasticSearch是什么:简称ES,是一个分布式、RESTful风格的搜索和数据分析引擎。
优势:
ES主要几个版本特性:
5.x版本(大转折)
发布时间:2016.10.26
主要特性
Lucene 6.x 的支持,磁盘空间少一半;索引时间少一半;查询性能提升25%;支持IPV6。
Internal engine级别移除了用于避免同一文档并发更新的竞争锁,带来15%-20%的性能提升
提供了第一个Java原生的REST客户端SDK IngestNode
提供了 Painless 脚本,代替Groovy脚本
新增了Profile API
新增了Rollover API
新增Reindex
提供了第一个Java原生的REST客户端SDK,基于HTTP协议的客户端对Elasticsearch的依赖解耦,没有jar包冲突,提供了集群节点自动发现、日志处理、节点请求失败自动进行请求轮询,充分发挥Elasticsearch的高可用能力
引入新的字段类型 Text/Keyword 来替换 String
限制索引请求大小,避免大量并发请求压垮 ES
限制单个请求的 shards 数量,默认 1000 个
仅支持非root用户启动
6.x版本
发布时间:2017.08.31
主要特性
稀疏性 Doc Values 的支持
Index sorting,即索引阶段的排序
Removal of types,在 6.0 里面,开始不支持一个 index 里面存在多个 type
已经关闭的索引将也支持 replica 的自动处理,确保数据可靠
Load aware shard routing, 基于负载的请求路由,目前的搜索请求是全节点轮询,那么性能最慢的节点往往会造成整体的延迟增加,新的实现方式将基于队列的耗费时间自动调节队列长度,负载高的节点的队列长度将减少,让其他节点分摊更多的压力,搜索和索引都将基于这种机制。
顺序号的支持,每个 es 的操作都有一个顺序编号(类似增量设计)无缝滚动升级
7.x版本
发布时间:2019.04.10
主要特性
集群连接变化:TransportClient被废弃以至于es7的java代码,只能使用restclient。对于java编程,建议采用 High-level-rest-client 的方式操作ES集群
ES程序包默认打包jdk
Lucene9.0的支持
正式废除单个索引下多Type的支持,es6时,官方就提到了es7会删除type,并且es6时已经规定每一个index只能有一个type。在es7中使用默认的_doc作为type,官方说在8.x版本会彻底移除type。,api请求方式也发送变化,如获得某索引的某ID的文档:GET index/_doc/id其中index和id为具体的值
7.1开始,Security功能免费使用
ECK-ElasticSearch Operator on Kubernetes,支持k8s
支持Zen2 是 Elasticsearch 的全新集群协调层,提高了可靠性、性能和用户体验,变得更快、更安全,并更易于使用
Weak-AND算法提高查询性能
默认的Primary Shared数从5改为1,避免Over Sharding
间隔查询(Intervals queries) 某些搜索用例(例如,法律和专利搜索)引入了查找单词或短语彼此相距一定距离的记录的需要。 Elasticsearch 7.0中的间隔查询引入了一种构建此类查询的全新方式,与之前的方法(跨度查询span queries)相比,使用和定义更加简单。 与跨度查询相比,间隔查询对边缘情况的适应性更强
支持arm平台的包下载,包括kibana,logstash
ES版本下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
找到对应版本下载
注:ES不允许使用root账号启动服务,当前账号是root 就要用 su "账户名" eg:su es,没有另外一个账号就需要创建一个
# 创建用户并赋予相应的权限
adduser es
passwd es
chown -R es:es .
使用7.x以上的ES可以使用自带的jdk环境,环境配置:
注意:yum -y install vim* 安装vim
1、输入命令 echo $ES_JAVA_HOME 如有显示出路径,说明已经进行了配置,否则继续下一步。
2、vim /etc/profile 在最下面添加,修改配置:
export ES_JAVA_HOME=/usr/local/es/elasticsearch-7.17.3/jdk
export ES_JRE_HOME=$ES_JAVA_HOME/jre
export CLASSPATH=$ES_JRE_HOME/lib:$ES_JRE_HOME/lib:$CLASSPATH
export PATH=$ES_JAVA_HOME/bin:$ES_JRE_HOME/bin:$PATH
3、 vim config/elasticsearch.yml 文件修改
# 加入如下配置
network.host: 0.0.0.0 #ES开启远程访问
cluster.name: elasticsearch
node.name: node-1
http.port: 9200
cluster.initial_master_nodes: ["node-1"]
4、修改虚拟机jvm堆内存大小 vim config/jvm.options
-Xms1g
-Xmx1g
5、修改/etc/security/limits.conf
# 在文件末尾中增加下面内容
# 每个进程可以打开的文件数的限制
es soft nofile 65536
es hard nofile 65536
6、修改/etc/security/limits.d/20-nproc.conf
# 在文件末尾中增加下面内容
# 每个进程可以打开的文件数的限制
es soft nofile 65536
es hard nofile 65536
# 操作系统级别对每个用户创建的进程数的限制
* hard nproc 4096
# 注: * 带表 Linux 所有用户名称
7、修改/etc/sysctl.conf
# 在文件中增加下面内容
# 一个进程可以拥有的 VMA(虚拟内存区域)的数量,默认值为 65536
vm.max_map_count=655360
8、修改完sysctl.conf 之后 需要重新加载
sysctl -p
9、默认配置,至少需要配置 discovery.seed_hosts / discovery.seed_providers / cluster.initial_master_nodes
discovery.seed_hosts: ["222.186.173.176"] #自己linux的地址
# discovery.seed_providers: 基于配置文件配置集群主机列表
cluster.initial_master_nodes: ["node-1"] #启动时初始化的参与选主的node,生产环境必填
启动ES
#非root用户 启动ES
bin/elasticsearch
# -d 后台启动
bin/elasticsearch -d
下载:https://github.com/medcl/elasticsearch-analysis-ik/releases 需要找到对应es的版本(版本相同)
下载完之后解压到es文件夹下的plugins目录下的ik目录(新建一个ik目录)
注:在线下载到这个文件夹下时,记得要把压缩包删除
自定义词库:
1:现在对应的es版本的ik分词器的 jdbc-reload.properties 配置中配置对应的数据库地址:
2:添加热更新线程HotDictReloadThread
- public class HotDictReloadThread implements Runnable {
-
- private static final Logger LOGGER = ESPluginLoggerFactory.getLogger(HotDictReloadThread.class.getName());
- @Override
- public void run() {
- while(true) {
- LOGGER.info("[==========]reload hot dict from mysql......");
- Dictionary.getSingleton().reLoadMainDict();
- }
- }
-
- }
并且需要启动热词字典加载线程,在 Dictionary 原文件中修改(找到 initial 方法中添加)
3:加载自定义数据库拓展词典到主词库表(在 Dictionary类中添加 loadExtendDictFromMysql 加载拓展词方法 与 loadStopDictFromMysql 加载停用词方法)
- public void loadExtendDictFromMysql(){
- Connection connection = null;
- Statement statement = null;
- ResultSet resultSet = null;
- try{
- Path file = PathUtils.get(getDictRoot(),"jdbc-reload.properties");
- props.load(new FileInputStream(file.toFile()));
- logger.info("loading jdbc-reload.properties");
- for (Object key : props.keySet()) {
- logger.info(key + "=" + props.getProperty(String.valueOf(key)));
- }
- logger.info(" hot dict " + props.getProperty("jdbc.reload.extend.sql"));
- connection = DriverManager.getConnection(
- props.getProperty("jdbc.url"),
- props.getProperty("jdbc.user"),
- props.getProperty("jdbc.password"));
- statement = connection.createStatement();
- resultSet = statement.executeQuery(props.getProperty("jdbc.reload.extend.sql"));
- while (resultSet.next()){
- // 加载扩展词典数据到主内存词典中
- String theWord = resultSet.getString("word");
- logger.info(theWord);
- _MainDict.fillSegment(theWord.trim().toLowerCase().toCharArray());
- }
- // 加载时间
- Thread.sleep(Integer.valueOf(String.valueOf(props.get("jdbc.reload.interval"))));
- }catch (Exception e){
- logger.error("[Extend Dict Loading] "+ e);
- }finally {
- if(resultSet != null){
- try {
- statement.close();
- } catch (SQLException e) {
- logger.error("[Extend Dict Loading] " + e);
- }
- }
- if(connection != null){
- try {
- connection.close();
- } catch (SQLException e) {
- logger.error("[Extend Dict Loading] " + e);
- }
- }
- }
- }
-
-
-
- public void loadStopDictFromMysql(){
- // 建立主词典实例
- _StopWords = new DictSegment((char) 0);
- Connection connection = null;
- Statement statement = null;
- ResultSet resultSet = null;
- try{
- Path file = PathUtils.get(getDictRoot(),"jdbc-reload.properties");
- props.load(new FileInputStream(file.toFile()));
- logger.info("loading jdbc-reload.properties");
- for (Object key : props.keySet()) {
- logger.info(key + "=" + props.getProperty(String.valueOf(key)));
- }
- logger.info(" stop dict " + props.getProperty("jdbc.reload.stop.sql"));
- connection = DriverManager.getConnection(
- props.getProperty("jdbc.url"),
- props.getProperty("jdbc.user"),
- props.getProperty("jdbc.password"));
- statement = connection.createStatement();
- resultSet = statement.executeQuery(props.getProperty("jdbc.reload.stop.sql"));
- while (resultSet.next()){
- // 加载扩展词典数据到主内存词典中
- String theWord = resultSet.getString("word");
- logger.info(theWord);
- _StopWords.fillSegment(theWord.trim().toLowerCase().toCharArray());
- }
- // 加载时间
- Thread.sleep(Integer.valueOf(String.valueOf(props.get("jdbc.reload.interval"))));
- }catch (Exception e){
- logger.error("[Stop Dict Loading] "+ e);
- }finally {
- if(resultSet != null){
- try {
- statement.close();
- } catch (SQLException e) {
- logger.error("[Stop Dict Loading] " + e);
- }
- }
- if(connection != null){
- try {
- connection.close();
- } catch (SQLException e) {
- logger.error("[Stop Dict Loading] " + e);
- }
- }
- }
- }
4:在 loadMainDict() 中添加自定义的加载拓展词的方法
5:在loadStopWordDict() 方法中添加自定义的加载停止词的方法
6:通过maven打包,
注意:我这里使用的是es自带的jdk,所以要把ip和端口开通socket网络链接权限
这个很重要!!!
到 es自带的 jdk/lib/security/default.policy文件中配置:
若不是使用es自带的jdk,那么常见的报错就是java.lang.ExceptionInInitializerError: null …access denied (“java.lang.RuntimePermission” “setContextClassLoader”)---配置内容位置相同
解决:
这是因为jdk权限不够
jdk14在/var/local/jdk-14.0.2/lib/security/default.policy中的grant{}里添加
jdk8是在/var/local/jdk1.8.0_271/jre/lib/security/java.policy中的grant{}里添加
permission java.lang.RuntimePermission "setContextClassLoader";
创建索引:索引命名必须小写,不能以下划线开头
#创建索引 注:对比关系型数据库,创建索引就等同于创建数据库。
PUT /es_db
#创建索引可以设置分片数和副本数
PUT /es_db
{
"setting" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
#查询索引
GET /es_db
#查询索引是否存在
HEAD /es_db
#删除索引
DELETE /ed_db
#关闭索引
POST /es_db/_close
#打开索引
POST /es_db/_open
#创建文档,指定id
PUT /es_db/_doc/1
{
"name":"张三",
"sex":1,
"age":25,
"address":"浙江杭州",
"remark":"初学es"
}
#创建文档,指定id
PUT /es_db/_create/2
{
"name":"李四",
"sex":2,
"age":18,
"address":"浙江杭州",
"remark":"初学es进阶"
}#查询文档前10条信息内容
GET /es_db/_doc/_search#查询对应id下的某一些信息
GET /es_db/_doc/1/_source
首先在pom中导入elasticsearch所需要的三个包
- <!-- 使用elasticsearch必须导入的三个包 -->
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>7.1.0</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-client</artifactId>
- <version>7.1.0</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- <version>7.1.0</version>
- </dependency>
- import org.apache.http.HttpHost;
- import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
- import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
- import org.elasticsearch.client.RequestOptions;
- import org.elasticsearch.client.RestClient;
- import org.elasticsearch.client.RestHighLevelClient;
-
- import java.io.IOException;
-
- public class CreateIndex {
-
- public static void main(String[] args) throws IOException {
- // 创建客户端对象
- RestHighLevelClient client = new RestHighLevelClient(
- RestClient.builder(new HttpHost("localhost", 9200, "http")));
-
- // 创建索引 - 请求对象
- CreateIndexRequest request = new CreateIndexRequest("user2");
- // 发送请求,获取响应
- CreateIndexResponse response = client.indices().create(request,
- RequestOptions.DEFAULT);
- boolean acknowledged = response.isAcknowledged();
- // 响应状态
- System.out.println("操作状态 = " + acknowledged);
-
- // 关闭客户端连接
- client.close();
- }
-
- }
- import org.apache.http.HttpHost;
-
- import org.elasticsearch.client.RequestOptions;
- import org.elasticsearch.client.RestClient;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.elasticsearch.client.indices.GetIndexRequest;
- import org.elasticsearch.client.indices.GetIndexResponse;
-
- import java.io.IOException;
-
- public class SearchIndex {
- public static void main(String[] args) throws IOException {
- // 创建客户端对象
- RestHighLevelClient client = new RestHighLevelClient(
- RestClient.builder(new HttpHost("localhost", 9200, "http")));
-
- // 查询索引 - 请求对象
- GetIndexRequest request = new GetIndexRequest("user2");
- // 发送请求,获取响应
- GetIndexResponse response = client.indices().get(request,
- RequestOptions.DEFAULT);
-
- System.out.println("aliases:"+response.getAliases());
- System.out.println("mappings:"+response.getMappings());
- System.out.println("settings:"+response.getSettings());
-
- client.close();
- }
- }
- import org.apache.http.HttpHost;
- import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
- import org.elasticsearch.action.support.master.AcknowledgedResponse;
- import org.elasticsearch.client.RequestOptions;
- import org.elasticsearch.client.RestClient;
- import org.elasticsearch.client.RestHighLevelClient;
-
- import java.io.IOException;
-
- public class DeleteIndex {
- public static void main(String[] args) throws IOException {
- RestHighLevelClient client = new RestHighLevelClient(
- RestClient.builder(new HttpHost("localhost", 9200, "http")));
- // 删除索引 - 请求对象
- DeleteIndexRequest request = new DeleteIndexRequest("user2");
- // 发送请求,获取响应
- AcknowledgedResponse response = client.indices().delete(request,RequestOptions.DEFAULT);
- // 操作结果
- System.out.println("操作结果 : " + response.isAcknowledged());
- client.close();
- }
- }
- import org.elasticsearch.client.RestHighLevelClient;
-
- public interface ElasticsearchTask {
-
- void doSomething(RestHighLevelClient client) throws Exception;
-
- }
- public class ConnectElasticsearch{
-
- public static void connect(ElasticsearchTask task){
- // 创建客户端对象
- RestHighLevelClient client = new RestHighLevelClient(
- RestClient.builder(new HttpHost("localhost", 9200, "http")));
- try {
- task.doSomething(client);
- // 关闭客户端连接
- client.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
使用这个通用方法使用lambda表达式新增一条文档数据,并且附上直接连接elasticsearch并添加数据
- package com.es.mian;
-
- import com.es.entity.User;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.apache.http.HttpHost;
- import org.elasticsearch.action.index.IndexRequest;
- import org.elasticsearch.action.index.IndexResponse;
- import org.elasticsearch.client.RequestOptions;
- import org.elasticsearch.client.RestClient;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.elasticsearch.common.xcontent.XContentType;
-
- import java.io.IOException;
-
- public class InsertDoc {
- public static void main(String[] args) {
- ConnectElasticsearch.connect(client -> {
- // 新增文档 - 请求对象
- IndexRequest request = new IndexRequest();
- // 设置索引及唯一性标识
- request.index("user2").id("1001");
-
- // 创建数据对象
- User user = new User();
- user.setName("李四");
- user.setAge(18);
- user.setSex("女");
-
- ObjectMapper objectMapper = new ObjectMapper();
- String productJson = objectMapper.writeValueAsString(user);
- // 添加文档数据,数据格式为 JSON 格式
- request.source(productJson, XContentType.JSON);
- // 客户端发送请求,获取响应对象
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
- //3.打印结果信息
- System.out.println("_index:" + response.getIndex());
- System.out.println("_id:" + response.getId());
- System.out.println("_result:" + response.getResult());
- });
- }
-
- /*public static void main(String[] args) throws IOException {
- // 传入IP地址和端口号
- HttpHost httpHost = new HttpHost("localhost", 9200, "http");
- // 创建客户端对象
- RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(httpHost));
- // 1.要在指定索引下创建文档,所以要先创建索引,再创建文档
- IndexRequest request=new IndexRequest();
- // index()方法设置索引名;id()方法设置唯一id标识
- request.index("user2").id("10001");
- // 2.创建实体类对象,填充数据
- User user=new User();
- user.setName("张三");
- user.setAge(30);
- user.setSex("男");
- // 3.利用jackson将实体类对象转换成JSON格式字符串
- ObjectMapper mapper=new ObjectMapper();
- String userJson = mapper.writeValueAsString(user);
- // 4.添加文档数据,数据格式为JSON格式
- request.source(userJson, XContentType.JSON);
- // 5.发送请求,获取响应结果
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
- System.out.println("_index: "+response.getIndex());
- System.out.println("_id: "+response.getId());
- System.out.println("_result: "+response.getResult());
- // 一番操作后,关闭客户端连接
- client.close();
- }*/
- }
-
- package com.es.mian;
-
- import org.elasticsearch.action.update.UpdateRequest;
- import org.elasticsearch.action.update.UpdateResponse;
- import org.elasticsearch.client.RequestOptions;
- import org.elasticsearch.common.xcontent.XContentType;
-
- public class UpdateDoc {
- public static void main(String[] args) {
- ConnectElasticsearch.connect(client -> {
- // 修改文档 - 请求对象
- UpdateRequest request = new UpdateRequest();
- // 配置修改参数
- request.index("user2").id("1001");
- // 设置请求体,对数据进行修改
- request.doc(XContentType.JSON, "name", "李四-修改之后的数据");
- // 客户端发送请求,获取响应对象
- UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
- System.out.println("_index:" + response.getIndex());
- System.out.println("_id:" + response.getId());
- System.out.println("_result:" + response.getResult());
- });
- }
-
- }
-
- package com.es.mian;
-
- import org.elasticsearch.action.get.GetRequest;
- import org.elasticsearch.action.get.GetResponse;
- import org.elasticsearch.client.RequestOptions;
-
- public class GetDoc {
- public static void main(String[] args) {
- ConnectElasticsearch.connect(client -> {
- //1.创建请求对象
- GetRequest request = new GetRequest().index("user2").id("1001");
- //2.客户端发送请求,获取响应对象
- GetResponse response = client.get(request, RequestOptions.DEFAULT);
- //3.打印结果信息
- System.out.println("_index:" + response.getIndex());
- System.out.println("_type:" + response.getType());
- System.out.println("_id:" + response.getId());
- System.out.println("source:" + response.getSourceAsString());
- });
- }
- }
-
-
- package com.es.mian;
-
- import org.elasticsearch.action.delete.DeleteRequest;
- import org.elasticsearch.action.delete.DeleteResponse;
- import org.elasticsearch.client.RequestOptions;
-
- public class DeleteDoc {
- public static void main(String[] args) {
- ConnectElasticsearch.connect(client -> {
- //创建请求对象
- DeleteRequest request = new DeleteRequest().index("user2").id("10001");
- //客户端发送请求,获取响应对象
- DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
- //打印信息
- System.out.println(response.toString());
- });
- }
- }
下载对应elasticsearch的版本的kibana eg:es版本为7.17.3 那么kibana下载7.17.3的版本
1、下载地址:https://www.elastic.co/cn/downloads/past-releases#kibana
2、对应压缩包放到对应目录 解压:tar -zxvf
批量对文档进行写操作失通过 _bulk 的API来实现的
-第一行参数为指定操作的类型及操作的对象(index,type和id)
-第二行参数才是操作的数据
参数类似于:
{“actionName”:{"_index":"indexName","_type":"typeName","_id":"id"}}
{"field1":"value1","field2":"value2"}
# actionName:表示操作类型,主要操作类型有 create,index,delete和update
_mget批量读取
#批量读取对应index下的文档id,没有指定索引的_mget
GET _mget
{
"docs": [
{
"_index":"es_db",
"_id": "1"
},
{
"_index":"user2",
"_id":"1"
},
{
"_index":"user2",
"_id":"2"}
]
}#批量读取index为user2下的文档id,指定索引
GET /user2/_mget
{
"docs": [
{
"_id": "1"
},
{
"_id":"2"
},
{
"_id":"3"
}
]
}#进一步简化
GET /user2/_mget
{
"ids":["1","2","3"]
}
_msearch: 在_msearch中,请求格式和bulk类似。查询一条数据需要两个对象,第一个设置index和type,第二个设置查询语句。查询语句和search相同。如果只是查询一个index,我们可以在url中带上indedx,这样,如果查询该index可以直接用空对象表示。
easy-es 接口官网:快速开始 | Easy-Es
easy-es 主要是es结合了mybatis-plus,使用方式与mybatis-plus一样。
- <!-- 引入easy-es最新版本的依赖-->
- <dependency>
- <groupId>cn.easy-es</groupId>
- <artifactId>easy-es-boot-starter</artifactId>
- <!--这里Latest Version是指最新版本的依赖,比如2.0.0,可以通过下面的图片获取-->
- <version>Latest Version</version>
- </dependency>
-
- <!-- 排除springboot中内置的es依赖,以防和easy-es中的依赖冲突-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>7.14.0</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- <version>7.14.0</version>
- </dependency>
Elasticsearch 基础语法:
- BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
-
- //wildcardQuery 通配符查询,支持* 任意字符串;?任意一个字符
- boolQuery.should(QueryBuilders.wildcardQuery("categoryId", "*"+item+"*"));
-
- //termsQuery 分词精确查询
- boolQuery.should(QueryBuilders.termsQuery("spuId", spuId));
-
- //matchPhraseQuery 顺序相同不是指字段值的内容完全包含关键词,而是指分词顺序相同。
- boolQuery.should(QueryBuilders.matchPhraseQuery("name", "黄山风景"));
- //注意:此时分词搜索,name 为 "安徽黄山风景区"的内容,搜索不出来,因为"安徽黄山风景区"和"黄山风景"分词,发现分词"山风"和"风景"之间还间隔了"风景区"这个分词,所以不符合条件。
- //解决可以设置slop解决分词间隔数量(分析:对第一条文档中的字段分词,"安徽黄山风景区"分词后发现安徽距离风景区相差两个字段,所以设置slop=2可以解决默认相隔字段为0的问题。)
- boolQuery.should(QueryBuilders.matchPhraseQuery("name", "黄山风景").slop(2))
-
- //matchQuery 即匹配查询。返回与提供的文本、数字、日期或布尔值匹配的文档。在匹配之前分析提供的文本。匹配查询是执行全文搜索的标准查询,包括模糊匹配选项。
- boolQuery.should(QueryBuilders.matchQuery("dosTitle","我爱中华"))
-
- //rangeQuery 范围查询
- boolQuery.should(QueryBuilders.boolQuery().must(
- QueryBuilders.boolQuery()
- //定时上架时间 大于等于当前时间
- .must(QueryBuilders.rangeQuery("offShelvesTime" ).gte(date.getTime()))
- //定时下架时间 小于等于当前时间
- .must(QueryBuilders.rangeQuery("putawayStartTime" ).lte(date.getTime())))
- );
-
-
- //条件写完之后,进行查询
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder()
- //查询条件
- .withQuery(boolQuery)
- //分页
- .withPageable(PageRequest.of(pageNum, pageSize))
- //排序
- .withSort(sortBuilders.scoreSort().order(SortOrder.DESC));
- val search = restTemplate.search(nativeSearchQueryBuilder.build(), EsGoodsSpuEs.class);
- for (SearchHit<EsGoodsSpuEs> searchHit : search.getSearchHits()) {
- list.add(searchHit.getContent());
- }
- map.put("total",search.getTotalHits()); //es搜索出来的总条数
- map.put("list",list); //当前页数据list
eg:"name" : {
"type" : "text",
"analyzer" : "ik_max_word"
},
3.使用matchPhraseQuery查询方法时,字段analyzer不要使用ik_max_word
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。