项目中使用全文搜索功能,上次使用es还是18年,使用的都是原生的查询,这次看到spring-data-es 已经更新到4.1.x了,直接可以使用注解完成各种查询及高亮处理
首先spring-data-es依赖,使用aliyun镜像,没找到4.1.x的springboot版本,使用的4.0.5 ,es 使用的7.9
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置和es连接
package com.example.demo.config;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("192.168.2.118:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
@Override
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter);
}
}
实体类
package com.example.demo.mode;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.Date;
import java.util.List;
/**
* 就诊病历记录
*
*/
@Document(indexName = "book1", type = "patient1")
public class VisitRecord {
@Id
@Field(type = FieldType.Text, store = true)
private String id;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String visitId;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String visitTypeCode;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String localSystemName;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String patientInfoId;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String visitTypeName;
@Field(type = FieldType.Date, format = DateFormat.custom ,pattern ="yyyy-MM-dd HH:mm:ss" ,store = true, analyzer = "standard")
private Date registrationDate;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String registrationDeptCode;
@Field(type = FieldType.Text, store = true, analyzer = "standard")
private String registrationDeptName;
@Field(type = FieldType.Date , format = DateFormat.custom ,pattern ="yyyy-MM-dd HH:mm:ss" , store = true, analyzer = "standard")
private Date visitDate;
@Field(type = FieldType.Date , format = DateFormat.custom ,pattern ="yyyy-MM-dd HH:mm:ss" , store = true, analyzer = "standard")
private Date admissionDate;
@Field(type = FieldType.Date , format = DateFormat.custom ,pattern ="yyyy-MM-dd HH:mm:ss" , store = true, analyzer = "standard")
private Date dischargeDate;
@Field(type= FieldType.Object)
private PatientInfo patientInfo; //个人基本信息
@Field(type= FieldType.Nested)
private List<Diagnose> dglist; //诊断
@Field(type= FieldType.Nested)
private List<ExamReport> erlist; //检查
@Field(type= FieldType.Nested)
private List<LabReport> lrlist; //检验
@Field(type= FieldType.Nested)
private List<Order> orlist; //医嘱
@Field(type= FieldType.Nested)
private List<Operation> oplist; //手术
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVisitId() {
return visitId;
}
public void setVisitId(String visitId) {
this.visitId = visitId;
}
public String getVisitTypeCode() {
return visitTypeCode;
}
public void setVisitTypeCode(String visitTypeCode) {
this.visitTypeCode = visitTypeCode;
}
public String getLocalSystemName() {
return localSystemName;
}
public void setLocalSystemName(String localSystemName) {
this.localSystemName = localSystemName;
}
public String getPatientInfoId() {
return patientInfoId;
}
public void setPatientInfoId(String patientInfoId) {
this.patientInfoId = patientInfoId;
}
public String getVisitTypeName() {
return visitTypeName;
}
public void setVisitTypeName(String visitTypeName) {
this.visitTypeName = visitTypeName;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public String getRegistrationDeptName() {
return registrationDeptName;
}
public void setRegistrationDeptName(String registrationDeptName) {
this.registrationDeptName = registrationDeptName;
}
public Date getVisitDate() {
return visitDate;
}
public void setVisitDate(Date visitDate) {
this.visitDate = visitDate;
}
public Date getAdmissionDate() {
return admissionDate;
}
public void setAdmissionDate(Date admissionDate) {
this.admissionDate = admissionDate;
}
public Date getDischargeDate() {
return dischargeDate;
}
public void setDischargeDate(Date dischargeDate) {
this.dischargeDate = dischargeDate;
}
public PatientInfo getPatientInfo() {
return patientInfo;
}
public void setPatientInfo(PatientInfo patientInfo) {
this.patientInfo = patientInfo;
}
public List<Diagnose> getDglist() {
return dglist;
}
public void setDglist(List<Diagnose> dglist) {
this.dglist = dglist;
}
public List<ExamReport> getErlist() {
return erlist;
}
public void setErlist(List<ExamReport> erlist) {
this.erlist = erlist;
}
public List<LabReport> getLrlist() {
return lrlist;
}
public void setLrlist(List<LabReport> lrlist) {
this.lrlist = lrlist;
}
public String getRegistrationDeptCode() {
return registrationDeptCode;
}
public void setRegistrationDeptCode(String registrationDeptCode) {
this.registrationDeptCode = registrationDeptCode;
}
public List<Order> getOrlist() {
return orlist;
}
public void setOrlist(List<Order> orlist) {
this.orlist = orlist;
}
public List<Operation> getOplist() {
return oplist;
}
public void setOplist(List<Operation> oplist) {
this.oplist = oplist;
}
@Override
public String toString() {
return "VisitRecord{" +
"id='" + id + '\'' +
", visitId='" + visitId + '\'' +
", visitTypeCode='" + visitTypeCode + '\'' +
", localSystemName='" + localSystemName + '\'' +
", patientInfoId='" + patientInfoId + '\'' +
", visitTypeName='" + visitTypeName + '\'' +
", registrationDate=" + registrationDate +
", registrationDeptCode='" + registrationDeptCode + '\'' +
", registrationDeptName='" + registrationDeptName + '\'' +
", visitDate=" + visitDate +
", admissionDate=" + admissionDate +
", dischargeDate=" + dischargeDate +
", patientInfo=" + patientInfo +
", dglist=" + dglist +
", erlist=" + erlist +
", lrlist=" + lrlist +
", orlist=" + orlist +
", oplist=" + oplist +
'}';
}
}
Repository接口
package com.example.demo.dao;
import com.example.demo.mode.VisitRecord;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.annotations.HighlightParameters;
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;
public interface BookRepository extends ElasticsearchRepository<VisitRecord, String> {
@Query("{\n" +
" \"multi_match\": {\n" +
" \"query\": \"?0\",\n" +
" \"fields\": [\n" +
" \"localSystemName\",\n" +
" \"visitTypeName\"\n" +
" ],\n" +
" \"analyzer\": \"standard\"\n" +
" }\n" +
"}")
@Highlight(
fields = {
@HighlightField(name = "localSystemName"),
@HighlightField(name = "visitTypeName")
},
parameters = @HighlightParameters(
preTags = "<strong><font style='color:red'>",
postTags = "</font></strong>",
fragmentSize = 500,
numberOfFragments = 3
)
)
List<SearchHit<VisitRecord>> findAllByByName(String name, Pageable pageable);
}
ServiceImpl
package com.example.demo.service.impl;
import com.example.demo.dao.BookRepository;
import com.example.demo.mode.BookBean;
import com.example.demo.mode.VisitRecord;
import com.example.demo.service.BookService;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
//import org.springframework.beans.factory.annotation.Qualifier;
@Service("blogService")
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookRepository")
private BookRepository bookRepository;
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
@Autowired
private RestHighLevelClient highLevelClient;
@Override
public void createIndex() {
//创建索引,并配置映射关系
boolean b = elasticsearchTemplate.indexOps(VisitRecord.class).create();
System.out.println("创建索引,并配置映射关系:"+b);
// elasticsearchTemplate.createIndex(VisitRecord.class);
//配置映射关系
// elasticsearchTemplate.indexOps(VisitRecord.class).createMapping(VisitRecord.class);
// elasticsearchTemplate.putMapping(Article.class);
}
@Override
public Optional<BookBean> findById(String id) {
return null;
//CrudRepository中的方法
// return bookRepository.findById(id);
}
@Override
public void addVisitRecord(VisitRecord visitRecord) {
bookRepository.save(visitRecord);
}
@Override
public BookBean save(BookBean blog) {
return blog;
// return bookRepository.save(blog);
}
@Override
public BookBean save1 (VisitRecord blog) {
// IndexQuery indexQuery = new IndexQueryBuilder().withObject(blog).build();
// String index = this.elasticsearchTemplate.index(indexQuery);
// System.out.println(index);
return null;
}
@Override
public void delete(BookBean blog) {
// bookRepository.delete(blog);
}
@Override
public Optional<BookBean> findOne(String id) {
return null;
// return bookRepository.findById(id);
}
@Override
public List<BookBean> findAll() {
return null;
// return (List<BookBean>) bookRepository.findAll();
}
@Override
public Page<BookBean> findByAuthor(String author, PageRequest pageRequest) {
return null;
// return bookRepository.findByAuthor(author,pageRequest);
}
@Override
public Page<BookBean> findByTitle(String title, PageRequest pageRequest) {
return null;
// return bookRepository.findByTitle(title,pageRequest);
}
@Override
public List<SearchHit<VisitRecord>> findAllByLSNAndNameOrderByName(String name, Pageable pageable){
return bookRepository.findAllByByName(name,pageable);
}
}
TEST类
package com.example.demo;
import com.example.demo.mode.LabReport;
import com.example.demo.mode.PatientInfo;
import com.example.demo.mode.VisitRecord;
import com.example.demo.service.BookService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@SpringBootTest(classes = DemoApplication.class)
class DemoApplicationTests {
@Autowired
private BookService bookService;
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
@Test
void contextLoads() {
// bookService.createIndex();
PatientInfo patientInfo = new PatientInfo();
patientInfo.setPatientName("用户姓名");
patientInfo.setIdentityNo("身份证");
patientInfo.setTelephone("电话");
patientInfo.setAddress("地址");
patientInfo.setBirthday(new Date());
LabReport labReport =new LabReport();
labReport.setItemCode("项目编号");
labReport.setItemName("项目名称");
LabReport labReport1 =new LabReport();
labReport1.setItemCode("项目编号1");
labReport1.setItemName("项目名称1");
List<LabReport> list = new ArrayList<LabReport>();
list.add(labReport);
list.add(labReport1);
VisitRecord visitRecord=new VisitRecord();
visitRecord.setId("123456791");
visitRecord.setVisitId("1234");
visitRecord.setVisitTypeCode("TYPE类型1");
visitRecord.setLocalSystemName("系统名称1");
visitRecord.setPatientInfoId("患者id");
visitRecord.setVisitTypeName("访问类型名称1");
visitRecord.setRegistrationDate(new Date());
visitRecord.setRegistrationDeptCode("注册编码");
visitRecord.setRegistrationDeptName("注册部门名称");
visitRecord.setVisitDate(new Date());
visitRecord.setAdmissionDate(new Date());
visitRecord.setDischargeDate(new Date());
visitRecord.setPatientInfo(patientInfo);
visitRecord.setLrlist(list);
System.out.println(visitRecord);
bookService.addVisitRecord(visitRecord);
}
@Test
void getMessage(){
VisitRecord visitRecord = elasticsearchTemplate.get("1234567", VisitRecord.class);
VisitRecord visitRecord1 = elasticsearchTemplate.get("123456789", VisitRecord.class);
Pageable pageable = PageRequest.of(0,3);
List<SearchHit<VisitRecord>> allByLSNAndNameOrderByName = bookService.findAllByLSNAndNameOrderByName("系统名称", pageable);
System.out.println(visitRecord);
}
}
解析SearchHit就可以看到获取的高亮信息了,比起原生获取高亮信息方便很多