springboot操作Elasticsearch
创始人
2025-05-29 22:13:04

一、版本说明

使用版本 ElasticSearch 7.17.3  springboot 2.7 Spring Data Elasticsearch 4.4.8 jdk不需要安装,会使用ES内置的JDK。

安装指定版本的ES,安装指定版本的Spring Boot,安装Spring Boot时选择依赖Spring Data Elasticsearch,spring boot指定了Spring Data Elasticsearch的版本。版本必须对应,否则Spring Data Elasticsearch和ES无法对应起来。

Spring Data Elasticsearch - Reference Documentation  查看版本对应关系。

看Spring Data Elasticsearch官方文档一定注意版本,版本不同,API差距很大,并且分清不同package下的同名类,很容易出错。

 && https://docs.spring.io/spring-data/elasticsearch/docs/4.4.8/reference/html/#preface.metadata &&  将url路径中的current或具体版本号修改为Spring Data Elasticsearch版本的版本号就可以查看对应版本文档

 

下图是查看spring boot中使用Spring Data Elasticsearch的版本号

二、安装ES 创建spring boot项目 

Elasticsearch是一个分布式全文搜索引擎,支持单节点模式(Single-Node Mode)和集群模式(Cluster Mode)部署,一 般来说,小公司的业务场景往往使用Single-Node Mode部署即可。以Single-Node Mode部署感受下ES,后续搭建分布式集群深入学习。

安装ES

1. 虚拟机环境准备

操作系统:CentOS 7.x 64 bit

客户端连接工具:SecureCRT关闭虚拟机的防火墙

systemctl stop firewalld.service #停止firewallsystemctl disable firewalld.service #禁止firewall开机启动firewall-cmd --state # 查看防火墙

2. Elasticsearch Single-Node Mode部署

我们在虚拟机上部署Single-Node Mode Elasticsearch

          下载Elasticsearch 地址: https://www.elastic.co/cn/downloads/elasticsearch 最新版本 。本课程使用7.3.0版本 。选择Linux版本下载 

 1.上传、解压tar.gz文件 

cd /opt/lagou/software
tar -zxvf elasticsearch-7.3.0-linux-x86_64.tar.gz -C ../servers

2.重命名

cd ../servers/
mv elasticsearch-7.3.0/ elasticsearch/

3 配置Elasticsearch

(1)编辑vim /opt/lagou/servers/elasticsearch/confifig/elasticsearch.yml

        单机安装请取消注释:node.name: node-1,否则无法正常启动。

        修改网络和端口,取消注释master节点,单机只保留一个node

node.name: node-1
network.host: 192.168.1.250
#
# Set a custom port for HTTP:
#
http.port: 9200
cluster.initial_master_nodes: ["node-1"]

(2)按需修改vim /opt/lagou/servers/elasticsearch/confifig/jvm.options内存设置

      vim /opt/lagou/servers/elasticsearch/config/jvm.options

     根据实际情况修改占用内存,默认都是1G,单机1G内存,启动会占用700m+然后在安装kibana后,基本上无 法运行了,运行了一会就挂了报内存不足。 内存设置超出物理内存,也会无法启动,启动报错。

      -Xms2g

      -Xmx2g

Exception in thread "main" java.nio.file.AccessDeniedException: /opt/es/elasticsearch-7.17.3/config/jvm.options.d  虚拟机内存设置好,或设置大一点 1G内存肯定不行,至少4G

3.添加es用户,es默认root用户无法启动,需要改为其他用户

useradd estest#修改密码passwd estest改变es目录拥有者账号chown -R estest /opt/lagou/servers/elasticsearch/

4.修改/etc/sysctl.conf

      ES因为需要大量的创建索引文件,需要大量的打开系统的文件,所以我们需要解除linux系统当中打开文件最大数目的限制,不然ES启动就会抛错

修改文件句柄数vim /etc/sysctl.conf末尾添加:vm.max_map_count=655360执行sysctl -p 让其生效sysctl -p

5.修改/etc/security/limits.conf

修改linux系统对文件描述符的限制级别vim /etc/security/limits.conf末尾添加:* soft nofile 65536* hard nofile 65536* soft nproc 4096* hard nproc 4096

6.启动es

切换刚刚新建的用户su estest启动命令/opt/lagou/servers/elasticsearch/bin/elasticsearch

7.配置完成:浏览器访问测试。 http://192.168.1.250:9200

8.Google商店安装head插件 就可以查看ES的运行状态或者使用Apipost自己调用接口。

我自己写的接口文件:  es接口查询

新建 Spring Boot项目

(1)新建spring boot 项目,选择Spring Data Elasticserach

 (2)新建repository实体类,映射Es中的index

package com.eb.fri.casebase.beanMappingESIndex;import lombok.Data;
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;@Document(indexName = "case")
@Data
public class Case {@IdString id;//单位@Field(type = FieldType.Text, analyzer = "ik_max_word")//发布时间 fielddata允许排序@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss")String publish_time;//date类型的数据想要排序,不需要设置fieldata。只需要看下索引是date类型即可。date类型可以进行排序。Test类型可以进行分词。
}

(3)新建接口继承ElasticsearchRepository

package com.eb.fri.casebase.repository;import com.eb.fri.casebase.beanMappingESIndex.Case;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import java.util.List;
import java.util.Optional;public interface ElasticsearchCaseRepository extends ElasticsearchRepository {@OverrideOptional findById(String s);/*** 模糊查询分页实现** @param pageable* @return //*/@Query(value = "   {\"fuzzy\": {\"article\": \"?0\"}}")Page findByArticleFussy(String kw, Pageable pageable);}

(4)application.yml配置

spring:elasticsearch:uris: 192.168.1.250:9200connection-timeout: 10

(5)配置spring boot内置支持的logback日志

      日志配置文件如果是下面文件名和位置,会被spring boot自动识别。 

    

    这句是开启Spring Data Elasticsearch的 查询语句日志。


%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n${LOG_APP_HOME}/base.%d{yyyy-MM-dd}.log${LOG_MAX_HISTORY}%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{500} - %msg%n

(5)controller调用

简单的CRUD使继承自ElasticsearchRepository接口的接口,复杂查询使用NativeSearchQuery构造查询条件。

package com.eb.fri.casebase.controller;import com.alibaba.fastjson.JSONObject;
import com.eb.fri.casebase.beanMappingESIndex.Case;
import com.eb.fri.casebase.repository.ElasticsearchCaseRepository;
import com.eb.fri.casebase.utils.SnowFlake;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @author liguofang* 对ES数据的查询 包括全文搜索、模糊搜索等*/
@RestController
@RequestMapping(value = "/es")
public class ESController {@AutowiredElasticsearchCaseRepository esrepo;@AutowiredElasticsearchOperations op;@ResponseBody@PostMapping(value = "/case/save")public String searchBy(@RequestBody Case caseObj) {caseObj.setId(SnowFlake.getID());Case res = esrepo.save(caseObj);return res.toString();}@GetMapping("/case/delete/{id}")public String deleteById(@PathVariable("id") Long id) {return "";}/*** 查询指定单位的文章,根据作者,文章内容等字段** @param pageable* @return*/@GetMapping("/case/searchDeptArticle")public SearchHits searchDeptArticle(String dept, String fields, @PageableDefault(sort = {"publish_time"}, direction = Sort.Direction.DESC) Pageable pageable) {JSONObject props_json = JSONObject.parseObject(fields);BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();boolQuery.must(QueryBuilders.matchQuery("dept", dept));for (String k : props_json.keySet()) {boolQuery.should(QueryBuilders.matchQuery(k, props_json.getString(k)));}NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()//查询条件.withQuery(boolQuery)//分页.withPageable(pageable).build();SearchHits searchHits = op.search(nativeSearchQuery, Case.class);return searchHits;}}

三、DSL操作

查询表达式 | Elasticsearch: 权威指南 | Elastic  官方中文文档版本比较旧,新版本没有中文版

Fuzzy query | Elasticsearch Guide [7.17] | Elastic  指定版本

理解bool组合查询

下面的查询用于查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。如果 两者 都满足。 即使数据中不满足should的数据也会查询出来,只不过评分低,排名靠后。

{"bool": {"must":     { "match": { "title": "how to make millions" }},"must_not": { "match": { "tag":   "spam" }},"should": [{ "match": { "tag": "starred" }},{ "range": { "date": { "gte": "2014-01-01" }}}]}
}

注意数据是否返回、对评分是否有影响。 

must 满足条件才返回

文档 必须 匹配这些条件才能被查询返回。

must_not 不满足条件才返回

文档 必须不 匹配这些条件才能被查询返回。

should 不影响返回,只影响得分

如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。不影响数据是否查询返回。

filter 必须满足条件才返回

必须 匹配条件才会查询返回。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。

将查询移到 bool 查询的 filter 语句中,这样它就自动的转成一个不评分的 filter 了。

{"bool": {"must":     { "match": { "title": "how to make millions" }},"must_not": { "match": { "tag":   "spam" }},"should": [{ "match": { "tag": "starred" }}],"filter": {"bool": { "must": [{ "range": { "date": { "gte": "2014-01-01" }}},{ "range": { "price": { "lte": 29.99 }}}],"must_not": [{ "term": { "category": "ebooks" }}]}}}
}

关键区分:输入是否进行分词、索引内字段Test类型一定进行分词、针对全部字段匹配还是单个字段匹配。输入是否进行错别字修改

分词查询:输入单词会进行分词,索引内的字段数据会进行分词。然后进行单个字段匹配或者全部字段匹配。 给定相似度排序结果。  match queryforstring实现

模糊查询:输入单词修改某几个字,然后和索引内分词的单个字段进行匹配。只能单字段,不能全部字段。 fussy regex实现

精确匹配:term实现。输入单词不进行分词,必须和文段分词完全匹配才可以。term实现。

对于分词的理解: Elasticsearch入门到精通第二篇-查询分析_木秀林的博客-CSDN博客

三、操作API

 开发流程

主要工作是开启Spring Data Elasticsearch日志后,对比输出的查询dsl和直接调用es的接口的dsl是否相同。 下面是es的官网中文文档

Spring Data Elasticsearch - Reference Documentation  4.4.8版本文档

Elasticsearch学习(7)—— 查询API - 叶枫啦啦的个人空间 - OSCHINA - 中文开源技术交流社区  

如何使用Spring Data Elasticsearch

(1) 自定义映射索引的实体类

package com.eb.fri.casebase.beanMappingESIndex;import lombok.Data;
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;@Document(indexName = "case")
@Data
public class Case {@IdString id;//单位@Field(type = FieldType.Text, analyzer = "ik_max_word")//发布时间 fielddata允许排序@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss")String publish_time;//date类型的数据想要排序,不需要设置fieldata。只需要看下索引是date类型即可。date类型可以进行排序。Test类型可以进行分词。
}
注解:@Document用来声明Java对象与ElasticSearch索引的关系indexName 索引名称(是字母的话必须是小写字母)type 索引类型shards 主分区数量,默认5replicas 副本分区数量,默认1createIndex 索引不存在时,是否自动创建索引,默认true不建议自动创建索引(自动创建的索引 是按着默认类型和默认分词器)
注解:@Id 表示索引的主键
注解:@Field 用来描述字段的ES数据类型,是否分词等配置,等于Mapping描述,其属性包括如下index 设置字段是否索引,默认是true,如果是false则该字段不能被查询store 标记原始字段值是否应该存储在 Elasticsearch 中,默认值为false,以便于快速检索。虽然store占用磁盘空间,但是减少了计算。type 数据类型(text、keyword、date、object、geo等)analyzer 对字段使用分词器,注意一般如果要使用分词器,字段的type一般是text。format 定义日期时间格式
注解:@CompletionField 定义关键词索引 要完成补全搜索analyzer 对字段使用分词器,注意一般如果要使用分词器,字段的type一般是text。searchAnalyzer 显示指定搜索时分词器,默认是和索引是同一个,保证分词的一致性。maxInputLength:设置单个输入的长度,默认为50 UTF-16 代码点

具体映射规则查看官网 Spring Data Elasticsearch - Reference Documentation 

注意事项

(1) test类型的字段想排序 必须设置fieldata 但是springboot的api设置无效。必须es api执行才可以。 

{"properties": {"publish_time": {"type": "text","fielddata": true}}
}

(2)date类型可以进行排序。

(3)排序字段为_score  _score才会有相似度分数值,如果排序字段为其他的字段,那么_score值为NaN  

(2)自定义接口实现ElasticsearchRepository接口

      首先实现映射索引的自定义实体类。       

     然后实现接口就可以使用一些关键词实现CRUD ES数据。常用来一些简单的操作,不能够实现复杂查询语句。因此,结合ElasticsearchOperations来查询。

package com.eb.fri.casebase.repository;import com.eb.fri.casebase.beanMappingESIndex.Case;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import java.util.List;
import java.util.Optional;public interface ElasticsearchCaseRepository extends ElasticsearchRepository {//继承来的方法@OverrideOptional findById(String s);//根据关键字实现查询指定的字段List> findByAuthor(String kw);/*** 分页实现** @param pageable* @return //*/@Query(value = "{\"match\": {\"article\": {\"query\": \"?0\"}}}")Page findByArticle(String kw, Pageable pageable);}

(2)使用ElasticsearchOperations 结合Queries实现查询

构造查询语句的三种方式

CriteriaQuery 隔离具体DSL,根据语义进行构造查询语句

StringQuery  使用ES DSL JSON请求体

NativeSearchQuery ES所有原生API都进行了实现

通过 NativeSearchQueryBuilder.withQuery(QueryBuilder1).withFilter(QueryBuilder2).withSort(SortBuilder1).withXXXX().build(); 这样的方式来完成 NativeSearchQuery 的构建。

QueryBuilder 主要用来构建查询条件、过滤条件,SortBuilder 主要是构建排序。

要构建 QueryBuilder,我们可以使用工具类 QueryBuilders,里面有大量的方法用来完成各种各样的 QueryBuilder 的构建,字符串的、Boolean 型的、match 的、地理范围的等等。

要构建 SortBuilder,可以使用 SortBuilders 来完成各种排序。

然后就可以通过 NativeSearchQueryBuilder 来组合这些 QueryBuilder 和 SortBuilder,再组合分页的参数等等,最终就能得到一个 SearchQuery 了。

SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery (QueryBuilders.queryStringQuery ("spring boot OR 书籍")).build ();

  @GetMapping("/case/searchDeptArticle")public SearchHits searchDeptArticle(String dept, String props, @PageableDefault(sort = {"publish_time"}, direction = Sort.Direction.DESC) Pageable pageable) {JSONObject props_json = JSONObject.parseObject(props);BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();boolQuery.must(QueryBuilders.matchQuery("dept", dept));for (String k : props_json.keySet()) {boolQuery.should(QueryBuilders.matchQuery(k, props_json.getString(k)));}NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()//查询条件.withQuery(boolQuery)//分页.withPageable(pageable).build();SearchHits searchHits = op.search(nativeSearchQuery, Case.class);return searchHits;}
Query query = new NativeSearchQueryBuilder().addAggregation(terms("lastnames").field("lastname").size(10)) //.withQuery(QueryBuilders.matchQuery("firstname", firstName)).build();SearchHits searchHits = operations.search(query, Person.class);

ElasticSearch系列(六)springboot中使用QueryBuilders、NativeSearchQuery实现复杂查询_雨剑yyy的博客-CSDN博客

QueryBuilders使用

QueryBuilders是ES中的查询条件构造器。下面结合一些具体的查询场景,分析其常用方法。

假设ES中已经有title为 “总裁关心浦东开发开放” 的数据;

ik_smart分词结果:

{"tokens": [{"token": "总裁","start_offset": 3,"end_offset": 6,"type": "CN_WORD","position": 1},{"token": "关心","start_offset": 6,"end_offset": 8,"type": "CN_WORD","position": 2},{"token": "浦东","start_offset": 8,"end_offset": 10,"type": "CN_WORD","position": 3},{"token": "开发","start_offset": 10,"end_offset": 12,"type": "CN_WORD","position": 4},{"token": "开放","start_offset": 12,"end_offset": 14,"type": "CN_WORD","position": 5}]
}

精确查询


精确,指的是查询关键字(或者关键字分词后),必须与目标分词结果完全匹配。

1.指定字符串作为关键词查询,关键词支持分词

//查询title字段中,包含 ”开发”、“开放" 这个字符串的document;相当于把"浦东开发开放"分词了,再查询;
QueryBuilders.queryStringQuery("开发开放").defaultField("title");//不指定feild,查询范围为所有feild
QueryBuilders.queryStringQuery("青春");//指定多个feild
QueryBuilders.queryStringQuery("青春").field("title").field("content");

2.以关键字“开发开放”,关键字不支持分词

QueryBuilders.termQuery("title", "开发开放")
QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2...")


3.以关键字“开发开放”,关键字支持分词

QueryBuilders.matchQuery("title", "开发开放")
QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3")


3.2 模糊查询


模糊,是指查询关键字与目标关键字可以模糊匹配。

1.左右模糊查询,其中fuzziness的参数作用是在查询时,es动态的将查询关键词前后增加或者删除一个词,然后进行匹配QueryBuilders.fuzzyQuery("title", "开发开放").fuzziness(Fuzziness.ONE)2.前缀查询,查询title中以“开发开放”为前缀的document;QueryBuilders.prefixQuery("title", "开发开放")3.通配符查询,支持*和?,?表示单个字符;注意不建议将通配符作为前缀,否则导致查询很慢QueryBuilders.wildcardQuery("title", "开*放")QueryBuilders.wildcardQuery("title", "开?放")

注意,
在分词的情况下,针对fuzzyQuery、prefixQuery、wildcardQuery不支持分词查询,即使有这种doucment数据,也不一定能查出来,因为分词后,不一定有“开发开放”这个词;

查询总结

   title为 “总裁关心浦东开发开放” 的数据

查询关键词  开发开放
queryStringQuery    查询目标中含有开发、开放、开发开放的    无    无
matchQuery    同queryStringQuery
termQuery    无结果,因为它不支持分词 无
prefixQuery    无结果,因为它不支持分词 无有,目标分词中以”开“开头的
fuzzyQuery    无结果,但是与fuzziness参数有关系
wildcardQuery    开发开放*无结果    开*,有放*,无

3.3 范围查询

//闭区间查询
QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2");//开区间查询,默认是true,也就是包含
QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2").includeUpper(false).includeLower(false);//大于
QueryBuilders.rangeQuery("fieldName").gt("fieldValue");
//大于等于
QueryBuilders.rangeQuery("fieldName").gte("fieldValue");
//小于
QueryBuilders.rangeQuery("fieldName").lt("fieldValue");
//小于等于
QueryBuilders.rangeQuery("fieldName").lte("fieldValue");


3.4 组合查询boolQuery()

QueryBuilders.boolQuery()
QueryBuilders.boolQuery().must();//文档必须完全匹配条件,相当于and
QueryBuilders.boolQuery().mustNot();//文档必须不匹配条件,相当于not
QueryBuilders.boolQuery().should();//至少满足一个条件,这个文档就符合should,相当于or



具体demo如下:

public void testBoolQuery() {NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("title", "开发")).should(QueryBuilders.termQuery("title", "青春")).mustNot(QueryBuilders.termQuery("title", "潮头"))).withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 50)).build();List articleEntities = elasticsearchRestTemplate.queryForList(nativeSearchQuery, ArticleEntity.class);articleEntities.forEach(item -> System.out.println(item.toString()));
}

以上是查询title分词中,包含“开发”或者“青春”,但不能包含“潮头”的document;也可以多个must组合。

SortBuilders排序


上述demo中,我们使用了排序条件:

//按照id字段降序
.withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC))

注意排序时,有个坑,就是在以id排序时,比如降序,结果可能并不是我们想要的。因为根据id排序,es实际上会根据_id进行排序,但是_id是string类型的,排序后的结果会与整型不一致。

建议:在创建es的索引mapping时,将es的id和业务的id分开,比如业务id叫做myId:

@Id
@Field(type = FieldType.Long, store = true)
private Long myId;@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
private String title;@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
private String content;

这样,后续排序可以使用myId进行排序。

分页


使用如下方式分页:

@Test
public void testPage() {NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("title", "青春")).withSort(SortBuilders.fieldSort("myId").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 50)).build();AggregatedPage page = elasticsearchRestTemplate.queryForPage(nativeSearchQuery, ArticleEntity.class);List articleEntities = page.getContent();articleEntities.forEach(item -> System.out.println(item.toString()));
}

注意,如果不指定分页参数,es默认只显示10条。

高亮显示


查询title字段中的关键字,并高亮显示:

@Test
public void test() {String preTag = "";String postTag = "";NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("title", "开发")).withPageable(PageRequest.of(0, 50)).withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC)).withHighlightFields(new HighlightBuilder.Field("title").preTags(preTag).postTags(postTag)).build();AggregatedPage page = elasticsearchRestTemplate.queryForPage(nativeSearchQuery, ArticleEntity.class,new SearchResultMapper() {@Overridepublic  AggregatedPage mapResults(SearchResponse response, Class clazz, Pageable pageable) {List chunk = new ArrayList<>();for (SearchHit searchHit : response.getHits()) {if (response.getHits().getHits().length <= 0) {return null;}ArticleEntity article = new ArticleEntity();article.setMyId(Long.valueOf(searchHit.getSourceAsMap().get("id").toString()));article.setContent(searchHit.getSourceAsMap().get("content").toString());HighlightField title = searchHit.getHighlightFields().get("title");if (title != null) {article.setTitle(title.fragments()[0].toString());}chunk.add(article);}if (chunk.size() > 0) {return new AggregatedPageImpl<>((List) chunk);}return null;}@Overridepublic  T mapSearchHit(SearchHit searchHit, Class type) {return null;}});List articleEntities = page.getContent();articleEntities.forEach(item -> System.out.println(item.toString()));
}

结果:

 title=勇立潮头——总裁关心浦东开发开放40, content=外交部

相关内容

热门资讯

【实验报告】实验一 图像的... 实验目的熟悉Matlab图像运算的基础——矩阵运算;熟悉图像矩阵的显示方法࿰...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
大模型落地比趋势更重要,NLP... 全球很多人都开始相信,以ChatGPT为代表的大模型,将带来一场NLP领...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
kuernetes 资源对象分... 文章目录1. pod 状态1.1 容器启动错误类型1.2 ImagePullBackOff 错误1....
STM32实战项目-数码管 程序实现功能: 1、上电后,数码管间隔50ms计数; 2、...
TM1638和TM1639差异... TM1638和TM1639差异说明 ✨本文不涉及具体的单片机代码驱动内容,值针对芯...
Qt+MySql开发笔记:Qt... 若该文为原创文章,转载请注明原文出处 本文章博客地址:https://h...
Java内存模型中的happe... 第29讲 | Java内存模型中的happen-before是什么? Java 语言...
《扬帆优配》算力概念股大爆发,... 3月22日,9股封单金额超亿元,工业富联、鸿博股份、鹏鼎控股分别为3.0...
CF1763D Valid B... CF1763D Valid Bitonic Permutations 题目大意 拱形排列࿰...
SQL语法 DDL、DML、D... 文章目录1 SQL通用语法2 SQL分类3 DDL 数据定义语言3.1 数据库操作3.2 表操作3....
文心一言 VS ChatGPT... 3月16号,百度正式发布了『文心一言』,这是国内公司第一次发布类Chat...
CentOS8提高篇5:磁盘分...        首先需要在虚拟机中模拟添加一块新的硬盘设备,然后进行分区、格式化、挂载等...
Linux防火墙——SNAT、... 目录 NAT 一、SNAT策略及作用 1、概述 SNAT应用环境 SNAT原理 SNAT转换前提条...
部署+使用集群的算力跑CPU密... 我先在开头做一个总结,表达我最终要做的事情和最终环境是如何的,然后我会一...
Uploadifive 批量文... Uploadifive 批量文件上传_uploadifive 多个上传按钮_asing1elife的...
C++入门语法基础 文章目录:1. 什么是C++2. 命名空间2.1 域的概念2.2 命名...
2023年全国DAMA-CDG... DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义...
php实现助记词转TRX,ET... TRX助记词转地址网上都是Java,js或其他语言开发的示例,一个简单的...
【分割数据集操作集锦】毕设记录 1. 按要求将CSV文件转成json文件 有时候一些网络模型的源码会有data.json这样的文件里...
Postman接口测试之断言 如果你看文字部分还是不太理解的话,可以看看这个视频,详细介绍postma...
前端学习第三阶段-第4章 jQ... 4-1 jQuery介绍及常用API导读 01-jQuery入门导读 02-JavaScri...
4、linux初级——Linu... 目录 一、用CRT连接开发板 1、安装CRT调试工具 2、连接开发板 3、开机后ctrl+c...
Urban Radiance ... Urban Radiance Fields:城市辐射场 摘要:这项工作的目标是根据扫描...
天干地支(Java) 题目描述 古代中国使用天干地支来记录当前的年份。 天干一共有十个,分别为:...
SpringBoot雪花ID长... Long类型精度丢失 最近项目中使用雪花ID作为主键,雪花ID是19位Long类型数...
对JSP文件的理解 JSP是java程序。(JSP本质还是一个Servlet) JSP是&#...
【03173】2021年4月高... 一、单向填空题1、大量应用软件开发工具,开始于A、20世纪70年代B、20世纪 80年...
LeetCode5.最长回文子... 目录题目链接题目分析解题思路暴力中心向两边拓展搜索 题目链接 链接 题目分析 简单来说࿰...