1. Elasticsearch—搜索应用服务器

  1.1 什么是搜索引擎

  搜索引擎(search engine )通常意义上是指:根据特定策略,运用特定的爬虫程序从互联网上搜集信息,然后对信息进行处理后,为用户提供检索服务,将检索到的相关信息展示给用户的系统。

  而我们讲解的是捜索的索引和检索,不涉及爬虫程序的内容爬取。大部分公司的业务也不会有爬取工作,而只提供查询服务,而且Elasticsearch也只是提供这方面的功能。

  1.2 认识 Elasticsearch

  Elasticsearch是一个分布式、RESTful风格的搜索和数据分析引撃。通过它,能够执行及合并多种类型的搜索(结构化数据、非结构化数据、地理位置、指标),解决不新涌现出的各种需求。

  Elasticsearch使用的是标准的RESTful风格的API,使用JSON提供多种语言(Java、 Python、.Net、SQL和PHP)的支持,它可以快速地存储、搜索和分析海量数据。

  Elasticsearch是用Java语言开发的,并使用Lucene作为其核心来实现所有索引和搜索的功能。它的目的是:通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

  Elasticsearch是一个开源的高扩展的分布式全文检索引擎,可以近乎实时地存储、检索数据; 本身扩展性很好,允许多台服务器协同工作,每台服务器可以运行多个实例。单个实例称为一个节(node), 一组节点构成一个集群(cluster)。分片是底层的工作单元,文档保存在分片内,分片又被分配到集群内的各个节点里,每个分片仅保存全部数据的一部分。

  当Elasticsearch的节点启动后,它会使用多播(multicast)或单播(用户更改了配置)寻找集群中的其他节点,并与之建立连接。

  1.3 Elasticsearch 应用案例

  • GitHub: 2013年年初,GitHub把Solr缓存改成了Elasticsearch,以便用户搜索20TB 的数据,包括13亿个文件和1300亿行代码。
  • 维基百科:启动以Elasticsearch为基础的核心搜索架构SoundCloud,为1.8亿用户提供即时而精准的音乐搜索服务。
  • 百度:百度使用Elasticsearch作为数据分析引擎,20多个业务税采集服务器上的各类数据及用户自定义数据,通过对各种数据进行多维分析,辅助定位异常。其单集群最大100台机器,200个Elasticsearch节点,每天导入超过30TB的数据。

除这些公司外,Stack Overflow、新浪、阿里、360、携程、有赞、苏宁都在使用它。它被广泛地用于各大公司的站内搜索、IT系统搜索(OA、CRM、ERP)、数据分析等工作中。

  1.4 对比 Elasticsearch 与 MySQL

  尽管将Elasticsearch与MySQL进行对比并不科学,但是这样的对比能区分Elasticsearch 和MySQL数据库的区别,便于快速用熟悉的知识来理解Elasticsearch 。所以,本节采用对比的方式来讲解Elasticsearch。Elasticsearch与MySQL的结构对比见表13-1。

  

  图 13-1

  • 关系型数据库中的数据库,相当于Elasticsearch中的索引(index )。
  • 一个数据库下面有多张表(table),相当于一个索引(index)下面有多个类型(type)。
  • 一个数据库表(table)下的数据由多行(row)多列(column属性)组成,相当于一个 type由多个文档(document)和多个field组成。
  • 在关系型数据库中,schema定义了表、每个表的字段,还有表和字段之间的关系;在 Elasticsearch中,mapping定义索引下的type的字段处理规则,即索引如何建立、索引类型、 是否保存原始索引 JSON文档、是否压缩原始JSON文档、是否需要分词处理、如何进行分词处理等。
  • 在 MySQL 数据库中的增(insert )、删(delete )、改(update )、查 ( select)操作相 当于 Elasticsearch 中的增(put/post )、删(delete )、改(update )、查(get)

  客户端主要通过"方法(PUT/POST/GET/ DELETE ) + http://ip:端口/索引名称/类型/主键” 来访问内容。

  1.5 认识 ElasticSearchRepository

  Spring-data-elasticsearch 是 Spring 提供的操作 Elasticsearch 的数据接口,它封装了大量的基础操作。通过它可以很方便地操作Elasticsearch的数据。

  通过继承ElasticsearchRepository来完成基本的CRUD及分页操作,和普通的 JPA没有什 么区别。比如下面实体Product的Repository继承ElasticsearchRepository后,可以在 Elasticsearch文档中进行查找和比较等操作。具体使用方法见以下代码:

@Component
public interface UserRepository extends ElasticsearchRepository<User,Long> {Optional<User> findById(Long id);User findByUsername(String username);List<User> findByEmail(String email);
}

  ElasticsearchRepository有几个特有的search方法,用来构建一些Elasticsearch查询, 主要由QueryBuilder和SearchQuery两个参数来完成一些特殊查询。

  实现类NativeSearchQuery实现了 QueryBuilder和SearchQuery方法,要构建复杂查询, 可以通过构建NativeSearchQuery类来实现。

  —般情况下,不是直接新建NativeSearchQuery类,而是使用NativeSearchQueryBuilder 来完成NativeSearchQuery的构建。具体用法见以下代码:

NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
builder.withQuery().withFilter().withSort().withXXX().build();

  1.6 认识 ElasticsearchTemplate

  

  ElasticsearchTemplate是Spring对Elasticsearch的API进行的封装,主要用来对索引进行创建、删除等操作。它继承了 ElasticsearchOperations 和 ApplicationContextAware 接口。 ElasticSearchTemplate 提供一些比 ElasticsearchRepository 更底层的方法。

  ElasticsearchOperations接口中常用的方法如下。

  • createlndex()方法:创建索引,返回值为布尔类型数据。
  • indexExists()方法:查询索引是否存在,返回值为布尔类型数据。
  • putMapping()方法:  创建映射,返回值为布尔类型数据。
  • getMapping()方法:得到映射,返回值为一个Map数据。
  • deletelndex()方法:删除索引,返回值为布尔类型数据。

  1.7 认识注解@Document

  注解@Document作用于类,用于标记实体类为文档对象。

  存储在Elasticsearch中的一条数据,即是一个文档,类似关系型数据库的一行数据。 Elasticsearch会索引每个文档的内容,以便搜索。它使用JSON格式,将数据存储到Elasticsearch 中,实际上是将JSON格式的字符串发送给了 Elasticsearch。

  1.document的核心元数据

  document有三个核心元数据,分别是 _index、_type、_id

  (1)_index。代表一个document存放在哪个index中,类似的数据放在一个索引中,非类似的数据放在不同的索引中。index中包含了很多类似的document,这些document的field很大一 部分是相同的。索引名称必须小写,不能用下画线开头,不包含逗号。

  (2)_type。代表document属于index的哪个类别,一个索引通常会划分为多个type,逻辑 index不同的数据进行分类。type名称可以是大写或小写,但是不能用下画线开头,不能包含逗号。

  (3)_id。代表document的唯一标识,与_index和_type —起可以标识和定位一个 document。默认自动创建id,也可以手动指定document的id。

  2.document id的手动指定和自动生成

  (1)手动指定 document id

  如果需要从某些其他系统中导入一些数据到Elasticsearch,则会采用手动指定id的形式,因 为一般情况下系统中已有数据的唯一标识,可以用作Elasticsearch中的document的id。

  其语法格式为:

put /index/type/id
{"json"
}

  (2)自动生成 document id

  其语法格式为:

post /index/type
{"json"
}

  自动生成的id长度为20个字符,URL安全、Base64编码、GUID、分布式系统并行生成时不会发生冲突。

  3. document的_source元数据,以及定制返回结果

  _source元数据是在创建document时放在body中的JSON数据。在默认情况下,查找数据时会返回全部数据。如果要定制返回结果,则可以指定_source中返回哪些field

  例如:

  GET /_index/_type/1?_source=field

  1.8 管理索引

    1. 创建索引

      (1)根据类的信息自动生成创建索引

        下面代码是根据实体类创建一个名为 "ec" 的索引,并定义type是“product”。由于是单机环境,所以定义副本为0,分片为默认值5。

@Data
@Document(indexName = "user",type = "user",replicas = 0,shards = 5)
public class User implements Serializable {private int id;private String username;private String password;
}

代码解释如下。

  • indexName :对应索引库名称,可以理解为数据库名。必须小写,否则会报 "org.elasticsearch.indices.InvalidlndexNameException"异常。
  • type:对应在索引库中的类型,可以将其理解为“表名”
  • shards:分片数量,默认值为5。
  • replicas:副本数量,默认值为1。如果是单机环境,则健康状态为“yellow”。如果要成为 "green”,则指定值为0即可。

      (2)手动创建索引

 可以使用createindex方法手动指定indexName和Settings,再进行映射。在使用前,要先注入ElasticsearchTemplate,使用方法如下。

  • 根据索引名创建索引:
elasticsearchTemplate.createIndex("indexname");
  • 根据类名创建索引:
elasticsearchTemplate.createIndex(User.class);

    2. 查询索引

  • 根据索引名查询:
elasticsearchTemplate.indexExists("indexname");
  • 根据类名查询:
elasticsearchTemplate.indexExists(User.class);

    3. 删除索引

    可以根据索引名和类名对索引进行删除。

  • 根据索引名删除:
elasticsearchTemplate.deleteIndex("indexname");
  • 根据类名删除:
elasticsearchTemplate.deleteIndex(User.class);

2. 用ELK管理Spring Boot应用程序的日志  

ELK 是 Elasticsearch+Logstash+Kibana 的简称。

Logstash负责将数据信息从输入端传输到输出端,比如将信息从MySQL传入Elasticsearch, 还可以根据自己的需求在中间加上滤网。Logstash提供了很多功能强大的滤网,以满足各种应用场景。

Logstash有以下两种工作方式。

  • 每一台机器启动一个Logstash服务,读取本地的数据文件,生成流传给Elasticsearch。
  • Logback引入Logstash包,然后直接生产JSON流,传给一个中心的Logstash服务器,Logstash服务器再传给Elasticsearch,最后,Elasticsearch将其流传给Kibana。

Kibana是一个开源的分析与可视化平台,和Elasticsearch —起使用。可以用Kibana搜索、 查看、交互存放在Elasticsearch索引里的数据。使用各种不同的图标、表格、地图等,Kibana能够很轻昜地展示高级数据分析与可视化。

ELK架构为数据分布式存储、日志解析和可视化创建了一个功能强大的管理链。三者相互配合, 取长补短,共同完成分布式大数据处理工作。

  2.1 安装 Elasticsearch

  (1)通过官网下载Elasticsearch。

  (2)在下载完成后,首先将其解压到合适的目录,然后进入解压目录下的bin目录,双击 bat文件启动Elasticsearch。这里需要确保安装的Java版本在1.8及以上。

   (3)访问“http://localhost:9200/”,当看到返回一串JSON格式的代码时,则说明已经安装成功了。

  根据应用需要,还可以安装Elasticsearch必要的一些插件,如Head、kibana、IK (中文分 词)、graph。

  2.2 安装 Logstash

  1. 安装 Logstash

  (1)访问 Elasticsearch 官网下载 Logstash

    (2)将下载文件解压到自定义的目录即可。

  2. 配置 Logstash

  (1 )在解压文件的config目录下新建log4j_to_es.conf文件,写入以下代码:

input {beats {port => 5044codec => "json"}
}output {elasticsearch {hosts => "127.0.0.1:9200"codec => json}
}

  这里一定要注意:这是UTF-8的格式,不要帯BOM。如果启动时岀现错误,则可以用“logstash -f ../config/xxx.conf -t“命令检查配置文件是否错误。

  (2)新建文件 run.bat。写入代码 logstash -f .\config\log4j_to_es.conf保存。然后双击该配置文件,启动Logstash。

    (3)访问 localhost:9600 如出现以下內容,则代表配置成功。

{"host":"DESKTOP-0VSQ1JE","version":"8.3.3","http_address":"127.0.0.1:9600","id":"f9a14845-005b-42f2-8725-9b3f67dafe86","name":"DESKTOP-0VSQ1JE","ephemeral_id":"9ffa0b64-c9bb-4385-8924-6565b4cd8167","status":"green","snapshot":false,"pipeline":{"workers":8,"batch_size":125,"batch_delay":50},"build_date":"2022-07-23T19:31:54Z","build_sha":"0205f0c5f2ff21118c161e769e8f2bbb79ee81a3","build_snapshot":false}

  2.3 安装Kibana

Kibana是官方推出的Elasticsearch数据可视化工具。

  (1)通过访问Elasticsearch官网下载Kibana。

  (2)解压下载的压缩文件,进入解压目录,双击Kibana目录的bin/kibana.bat,以启动 Kibana,当岀现以下提示时,代表启动成功。

  [2022-08-16T16:30:45.443+08:00][INFO ][status] Kibana is now available (was degraded)

  (3)访问localhost:5601就可以逬入Kibana控制台。

  单击控制台左边导航栏的“Dev-tools”按钮,可以进入Dev-tools界面。单击"Get to work", 然后在控制台输入“GET/_cat/health?”命令,可以查看服务器状态。如果在右侧返回的结果中看到green或yellow ,则表示服务器状态正常。

  2.4 配置 Spring Boot 项目

  (1)添加项目依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j</artifactId><version>1.3.6.RELEASE</version>
</dependency>
<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>7.2</version>
</dependency>

  (2)添加配置文件logback.xml,这里在Spring Boot项目里添加一个配置又件,见以下代码:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration><appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"><destination>localhost:9601</destination><encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/></appender><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder charset="UTF-8"><pattern>%d{HH:mm:ss.SSS}[%thread]%-5level %logger - %msg%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="LOGSTASH"/><appender-ref ref="STDOUT"/></root>
</configuration>

  2.5 创建日志计划任务

  在Spring Boot项目中创建logTest类,用于测试将日志通过Logstash发送到Elasticsearch, 见以下代码:

3. Spring Boot集成Elasticsearch

  实现增加、删除、修改、查询文档的功能

  3.1 集成 Elasticsearch

Spring Boot 提供了 Starter ( spring-boot-starter-data-elasticsearch )来集成 Elasticsearch

  • 优点:开发速度快,不要求熟悉Elasticsearch的一些API,能快速上手。即使之前对 Elasticsearch不了解,也能通过方法名或SQL语句快速写岀自己需要的逻辑。而具体转换成API层的操作则是由框架底层实现的。
  • 缺点:使用的Spring Boot的版本Elasticsearch的版本也有了要求,不能超过某些版本号,在部署时需要注意。如果采用API方式,则能解决这个问题。

  (1)添加依赖

<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId>
</dependency>

  (2)添加application.yml配置

spring:data:elasticsearch:repositories:enabled: true #是否开启本地存储cluster-nodes: 127.0.0.1:9200cluster-name: elasticsearch

  3.2 创建实体

  (1)创建实体

  这里根据类的信息自动生成,也可以手动指定索引名称。ElasticsearchTemplate中提供了创建素引的API,因为进行本机测试,没做集群,所以replicas副本先设置为0。见以下代码:

package com.intehel.demo.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;import java.io.Serializable;@Document(indexName = "ec",replicas = 0,shards = 5,type = "product")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product implements Serializable {//@Id注解必须是org.springframework.data.annotation.Id;@Idprivate Long id;//ik_max_word使用ik分词器@Field(type = FieldType.Text,analyzer = "ik_max_word")private String name;//在存储数据时,不会对category进行分词@Field(type = FieldType.Keyword)private String category;//价格@Field(type = FieldType.Double)private Double price;//index = false 表示不建立索引@Field(index = false,type = FieldType.Keyword)private String images;private String body;
}

代码解释如下,

  • @ld注解:作用于成员变量,标记一个字段作为id主键。
  • @Field注解:作用于成员变量,标记为文档的字段,需要指定字段映射属性type。
  • index:是否索引,布尔类型,默认为true。
  • store:是否存储,布尔类型,默认为false,
  • analyzer;分词器名称,这里的ik_max_word即使用IK分词器。

  (2)创建数据操作接口

package com.intehel.demo.repository;import com.intehel.demo.domain.Product;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.Optional;public interface ProductRepository extends ElasticsearchRepository<Product,Long> {@OverrideOptional<Product> findById(Long id);Product findByName(String name);
}

  3.3 实现增加、删除、修改和查询文档的功能

  在测试类中,实Elasticsearch文档进行增加、删除、修改和查询的功能,见以下代码:

查看代码

 package com.intehel.demo;import com.intehel.demo.domain.Product;
import com.intehel.demo.domain.User;
import com.intehel.demo.repository.ProductRepository;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;import java.util.Optional;@SpringBootTest
@RunWith(SpringRunner.class)
class ElasticApplicationTests {private Integer PAGESIZE = 10;@Autowiredprivate ProductRepository productRepository;@Testpublic void save(){long id = System.currentTimeMillis();Product product = new Product(id,"红富士","水果",7.99,"jpg","测试");try {productRepository.save(product);}catch (Exception e){e.printStackTrace();}System.out.println(product.getId());}@Testpublic void getProduct(){Product product = productRepository.findByName("红富士");System.out.println(product.getId());}@Testpublic void updateProduct(){long id = 1660653233939L;Product product = new Product(id,"烤冷面","小吃",7.00,"jpg","测试");productRepository.save(product);}@Testpublic void getProductById(){Optional<Product> product = productRepository.findById(1660653233939L);System.out.println(product.get().getName()+product.get().getBody());}@Testpublic void deleteProduct(){long id = 1660653233939L;productRepository.deleteById(id);}@Testpublic void getAll(){Iterable<Product> list = productRepository.findAll(Sort.by("id").ascending());for (Product product : list) {System.out.println(product);}}
}

4. Elasticsearch查询

  4.1 自定义方法

   可以根据Spring Data提供的方法名称,实现自己想自定义的查询功能:无须写实现类,只要继承ElasticsearchRepository接口即可。如"findByTitle"表示根据"title”进行查询,具体方法见表13~2

  

图 13-2

  如果要查询价格在7 ~ 8元的商品,则可以在接口类加上"List<Product> findByPriceBetween(Double min, Double max);"方法,见以下代码:

public interface ProductRepository extends ElasticsearchRepository<Product,Long> {@OverrideList<Product> findByPriceBetween(Double min, Double max);
}

  然后,在测试类中直接使用自定义的"findByPriceBetween"方法查询出数据,见以下代码:

@Test
public void queryByPriceBetween(){Iterable<Product> list = productRepository.findByPriceBetween(7.00,8.00);for (Product product : list) {System.out.println(product);}
}

  4.2 精准查询

  1.单参数 termQuery

  用法见以下代码:

QueueBuilder queueBuilder = QueueBuilder.termQuery("字段名","查询值");

它是不分词查询。因为不分词,所以汉字只能查询一个字,而多字母的英语单词算一个字

具体实现见以下代码:

@Test
public void queryByPriceBetween(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.termQuery("name","富"));//查询词,只能查询一个汉字,或一个英文单词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  2.多参数--termsQuery

  terms可以提供n个查询的参数对一个字段进行查询,用法见以下代码。注意,这里是term的复数形式terms

  QueueBuilder queueBuilder = QueueBuilder.termsQuery("字段名","查询值","查询值");

@Test
public void queryByPriceBetween(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.termsQuery("name","富","帅"));//查询词,只能查询一个汉字,或一个英文单词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}}

  3.分词查询-- matchQuery

  分词查询采用默认的分词器.用法见以下代码

  QueueBuilder queueBuilder = QueueBuilder.matchQuery("字段名","查询值");

  具体实现见以下代码:

@Test
public void matchQuery() throws Exception {}{NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.matchQuery("name","红士"));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  4.多字段查询 multiMatchQuery

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.multiMatchQuery("红富士Gila","name","body"));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  4.3 模糊查询

  常见的模糊查询的方法有4种

  1.左右模糊

QueryBuilders.queryStringQuery("查询值").field("字段名")

  具体实现见以下代码:

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.queryStringQuery("我觉得红富士好吃").field("name"));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  2. 前缀查询--- prefixQuery

  如果字段没分词,则匹配整个字段前缀,用法见以下代码:

QueryBuilders.prefixQuery("字段名","查询值")

  具体实现见以下代码:

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.prefixQuery("name","士"));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  3. 通配符查询  wildcard query

  使用通配符方式进行查询,支持通配符”*“和”?“,”*“代表任意字符串,”? ”代表任意一个字符。

  (1)使用通配符”*“

  通配符可以匹配多个值,用法见以下代码:

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.wildcardQuery("name","*士"));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  (2)使用通配符“?”

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.wildcardQuery("name","红富?"));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  4. 分词模糊査询   fuzzy query

  分词模糊查询即匹配截取字符串为字前或后加1个词的文档,这里通过增加fuzziness (模糊) 属性来查询,fuzziness的含义是检索的term前后增加或减少n个词的匹配查询。用法见以下代码

QueryBuilders.fuzzyQuery("字段名","查询值").fuzziness(Fuzziness.ONE)

  具体实现见以下代码:

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.fuzzyQuery("name","士").fuzziness(Fuzziness.ONE));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  5. 相似内容推荐

  相似内容的推荐是给定一篇文档信息,然后向用户推荐与该文档相似的文档。通过 Elasticsearch的More like this查询接口,可以非常方便地实现基于内容的推荐,用法见以下代码: QueryBuilders.moreLikeThisQuery(new StnngQ ("WfiS"}).addLikeText("@i®ffi");

  如果不指定字段名,则默认全部,常用在相似内容的推荐上。

  QueryBuilders.moreLikeThisQuery(new String[]{"字段名"}).addLikeText("查询值")

  4.4 范围查询

  闭区间查询:QueryBuilders.rangeQuery("字段名").from("值1").to("值2")

  开区间查询:QueryBuilders.rangeQuery("字段名").from("值1").to("值2").includeLower(false).includeUpper(false)

  大于:QueryBuilders.rangeQuery("字段名").gt("查询值")

  大于或等于:QueryBuilders.rangeQuery("字段名").gte("查询值")

  小于:QueryBuilders.rangeQuery("字段名").lt("查询值")

  小于或等于:QueryBuilders.rangeQuery("字段名").lte("查询值")

  4.5 组合查询

组合查询是可以设置多个条件的查询方式,用来组合多个查询。有4种方式。

  • must:代表文档必须完全匹配条件,相当于and,会参与计算分值。
  • mustnot:代表必须不满足匹配条件。
  • filter:代表返回的文档必须满足filter条件,但不会参与计算分值。
  • should:代表返回的文档可能满足条件,也可能不满足条件,有多个should时满足任何一 个就可以,相当于or,可以通过minimum_should_match设置至少满足几个。

  4.6 分页查询

  使用NativeSearchQueryBuilder实现分页查询,用法见以下代码:

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.termQuery("name","富"));nativeSearchQueryBuilder.withPageable(PageRequest.of(0,5));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  如果要进行排序,只要在分页查询上构建withSort参数即可,用法见以下代码:

@Test
public void matchQuery(){NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(QueryBuilders.termQuery("name","富"));nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC));nativeSearchQueryBuilder.withPageable(PageRequest.of(0,5));//查询词Page<Product> page = productRepository.search(nativeSearchQueryBuilder.build());//搜索,获取结果for (Product product : page){System.out.println(product);}
}

  4.7 聚合查询

  聚合(aggregation )是Elasticsearch的一个强大功能,可以极其方便地实现对数据的统计、分析工作。搜索是查找某些具体的文档,聚合就是对这些搜索到的文档进行统计,可以聚合出更加细致的数据。它有两个重要概念。

  • Bucket (桶/集合):满足特定条件的文档的集合,即分组。
  • Metric (指标/度量):对桶内的文档进行统计计算(最小值、最大值),简单理解就是进行运算

聚合由AggregationBuilders类来构建,它提供的静态方法见表13-3

  

表 13-3

  具体用法见以下代码:

public List<StringTerms.Bucket> searchBybucket(){NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""},null));//指定索引的类型,只先从各分片中查询匹配的文档,再重新排名,取前size个文档queryBuilder.withSearchType(SearchType.QUERY_THEN_FETCH);//添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brandqueryBuilder.addAggregation(AggregationBuilders.terms("brand").field("brand"));//查询,需要把结果强转为Aggregatedpage类型,Aggregatedpage:聚合查询的结果类,它是Page<T>的子接口AggregatedPage<Product> productsPage = (AggregatedPage<Product>) productRepository.search(queryBuilder.build());//从结果中取出名为brands的聚合解析//强转为StringTerm类型StringTerms aggregations = (StringTerms) productsPage.getAggregation("brands");//获取桶List<StringTerms.Bucket> buckets = aggregations.getBuckets();//遍历for (StringTerms.Bucket bucket : buckets) {//获取桶中的keySystem.out.println(bucket.getKey());//获取桶中的文档数量System.out.println(bucket.getDocCount());}return buckets;
}

  还可以嵌套聚合,在聚合AggregationBuilders中使用subAggregation,用法见以下代码:

queryBuilder.addAggregation(AggregationBuilders.terms("brand").field("brand").subAggregation(AggregationBuilders.avg("price_avg").field("price"))//在品牌聚合桶内进行嵌套聚合);

spring boot集成Elasticsearch-SpringBoot(25)相关推荐

  1. 第 4-8 课:Spring Boot 集成 ElasticSearch

    ElasticSearch 是⼀个开源的搜索引擎,建⽴在⼀个全⽂搜索引擎库 Apache Lucene™ 基础之上. Lucene 可以说是当下最先进.⾼性能.全功能的搜索引擎库--⽆论是开源还是私有 ...

  2. Spring Boot 集成 Elasticsearch 实战

    今天讲解下如何使用 Spring Boot 结合 ES. 可以在 ES 官方文档中发现,ES 为 Java REST Client 提供了两种方式的 Client:Java Low Level Cli ...

  3. spring boot集成Elasticsearch客户端

    spring boot整合Elasticsearch客户端 在spring boot程序应用中集成Elasticsearch客户端,并通过配置对连接进行管理. Elasticsearch的客户端Jav ...

  4. Spring Boot 集成 ElasticSearch,实现高性能搜索

    1.ElasticSearch介绍 Elasticsearch 是java开发的,基于 Lucene 的搜索引擎.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful Web接口.Elast ...

  5. Spring Boot 集成 Elasticsearch

    Elasticsearch (简称ES) 是一个基于 Lucene 的分布式.高扩展.高实时的搜索与数据分析引擎.本章介绍 Spring Boot 应用集成 Elasticsearch ,通过 Spr ...

  6. ElasticSearch——Spring Boot 集成 ES 操作详解

    文章目录 ElasticSearch--Spring Boot 集成 ES 操作详解 1.SpringBoot 集成 ES 2.索引的API操作详解 3.文档的API操作详解 ElasticSearc ...

  7. springboot 单测加入参数_Spring Boot集成Elasticsearch实战分享

    作者|java梦想口服液|简书 最近有读者问我能不能写下如何使用 Spring Boot 开发 Elasticsearch(以下简称 ES) 相关应用,今天就讲解下如何使用 Spring Boot 结 ...

  8. ideal新建springboot工程_MyBatis初级实战之一:Spring Boot集成

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. springboot(十八):使用Spring Boot集成FastDFS

    上篇文章介绍了如何使用Spring Boot上传文件,这篇文章我们介绍如何使用Spring Boot将文件上传到分布式文件系统FastDFS中. 这个项目会在上一个项目的基础上进行构建. 1.pom包 ...

最新文章

  1. JS加法函数,用来得到精确的加法结果(说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果)
  2. 【Leetcode】100. 相同的树
  3. 高性能IO设计中的Reactor模式与Proactor模式
  4. torch.var()、样本方差、母体方差
  5. springcloud 组件_深入理解 Spring Cloud 核心组件与底层原理
  6. java为什么要定义接口_java为什么要定义接口等相关解释
  7. 如何修改Win7开机登陆界面背景图片
  8. 初学Spring Boot
  9. 【c语言数据结构】二叉树
  10. JasperReport里面的Demo
  11. docker mysql主从复制
  12. Python对象的比较、拷贝
  13. 【NOIP2016】【Luogu1909】买铅笔(模拟)
  14. Screaming Frog SEO Spider的11个鲜为人知的功能
  15. drivers/mfd/Mfd-core.c
  16. 虚拟仿真实验室 服务器,汽车学院虚拟仿真实验室平台
  17. 艾尔登法环绝配:iGame加推双风扇白色版RTX 3050
  18. 37Java流程控制-打印三角形及debug练习
  19. 未婚同居能白头偕老吗
  20. 环游世界,走遍读过的每一个国家和城镇

热门文章

  1. Eclipse Android开发入门手册
  2. win7防火墙对nmap扫描的反应
  3. Java实现_算法_并查集
  4. 计算机病毒检测外文文献,外文文献翻译 计算机网络病毒与防范.doc
  5. mysql timezone上海_MySql的时区(serverTimezone)引发的血案
  6. tooltip 控件
  7. iOS 13 Scene Delegate and multiple windows
  8. HTML基础的学习(1)(HBuilder快捷键)
  9. 二代测序(NGS)常用数据格式
  10. python的多线程与多进程