1、創建SpringBoot工程。
spring boot版本為2.2.6, 增加spring-boot-starter-data-elasticsearch
<?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.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>sp-esearch</artifactId> <version>0.0.1-SNAPSHOT</version> <name>sp-esearch</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</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <!--<version>2.2.2.RELAESE</version>--> </dependency> </dependencies> </project>
2、增加配置
spring: data: elasticsearch: cluster-name: elasticsearch cluster-nodes: 127.0.0.1:9300
3、使用單元測試創建索引
@SpringBootTest class SpEsearchApplicationTests { @Test void contextLoads() { } }
創建Student類
@Document(indexName = "stu", type = "_doc") public class Student { @Id private Long stuId; @Field(store = true) private String name; @Field(store = true) private Integer age; public Long getStuId() { return stuId; } public void setStuId(Long stuId) { this.stuId = stuId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
創建索引
public class ESTest extends SpEsearchApplicationTests { @Autowired private ElasticsearchTemplate esTemplate; //創建索引 @Test public void createIndex(){ Student stu = new Student(); stu.setStuId(1000L); stu.setName("Nick"); stu.setAge(20); IndexQuery indexQuery = new IndexQueryBuilder().withObject(stu).build(); esTemplate.index(indexQuery); } }
執行單元測試方法,結果顯示索引已經創建成功
數據瀏覽
4、刪除索引
@Test public void deleteIndex(){ esTemplate.deleteIndex(Student.class); }
注意: 不建議使用ElasticsearchTemplate對索引進行管理(創建索引,更新映射,刪除索引)。
索引就像是數據庫或者數據庫中的表,我們平時不會通過Java代碼頻繁的去創建修改刪除數據庫或者表,之后針對數據做CRUD操作,在es中也是同理,
5、更新文檔數據。
Id為1000這條數據
@Test public void updateStuDoc(){ Map<String,Object> source = new HashMap<>(); source.put("sign","I am not a english teacher"); source.put("money",88.8f); source.put("age","100"); IndexRequest indexRequest = new IndexRequest(); indexRequest.source(source); UpdateQuery query = new UpdateQueryBuilder().withClass(Student.class) .withId("1000") .withIndexRequest(indexRequest) .build(); esTemplate.update(query); }
6、查詢文檔數據
@Test public void getStuInfo(){ GetQuery getQuery = new GetQuery(); getQuery.setId("1000"); Student student = esTemplate.queryForObject(getQuery, Student.class); System.out.println(student); }
返回結果
Student{stuId=1000, name='Nick 2', age=100, money=88.8, sign='I am not a english teacher', description='I am a english teacher'}
7、刪除文檔數據
@Test public void deleteStuDoc(){ esTemplate.delete(Student.class,"1000"); }
8、文檔分頁查詢
1) 創建5條數據
@Test public void createIndex(){ for(int i = 0 ; i < 5; i++){ Student stu = new Student(); stu.setStuId(1000L + i); stu.setName("Nick" + i); stu.setAge(20 + i); stu.setMoney(18.9f + i); stu.setSign("I am a teacher"); stu.setDescription("I am a english teacher " + i); IndexQuery indexQuery = new IndexQueryBuilder().withObject(stu).build(); esTemplate.index(indexQuery); } }
2) 分頁查詢
@Test public void searchStuDoc(){ Pageable pageable = PageRequest.of(0,10); SearchQuery query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("description","a teacher")) .withPageable(pageable).build(); AggregatedPage<Student> pageStu = esTemplate.queryForPage(query,Student.class); System.out.println("總分頁數:" + pageStu.getTotalPages()); List<Student> stuList = pageStu.getContent(); for(Student student : stuList){ System.out.println(student); } }
返回結果如下:
總分頁數:1 Student{stuId=1000, name='Nick0', age=20, money=18.9, sign='I am a teacher', description='I am a english teacher 0'} Student{stuId=1001, name='Nick1', age=21, money=19.9, sign='I am a teacher', description='I am a english teacher 1'} Student{stuId=1002, name='Nick2', age=22, money=20.9, sign='I am a teacher', description='I am a english teacher 2'} Student{stuId=1003, name='Nick3', age=23, money=21.9, sign='I am a teacher', description='I am a english teacher 3'} Student{stuId=1004, name='Nick4', age=24, money=22.9, sign='I am a teacher', description='I am a english teacher 4'}
8、文檔高亮查詢
@Test public void highlightStuDoc(){ String preTag = "<font color='red'>"; String postTag = "</font>"; Pageable pageable = PageRequest.of(0,2); SearchQuery query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("description","a teacher")) .withHighlightFields(new HighlightBuilder.Field("description").preTags(preTag).postTags(postTag)) .withPageable(pageable).build(); AggregatedPage<Student> pageStu = esTemplate.queryForPage(query, Student.class, new SearchResultMapper() { @Override public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) { List<Student> stuHighlight = new ArrayList<>(); SearchHits hits = searchResponse.getHits(); for(SearchHit h: hits){ HighlightField highlightField = h.getHighlightFields().get("description"); Integer stuId = (Integer)h.getSourceAsMap().get("stuId"); String name = (String)h.getSourceAsMap().get("name"); Integer age = (Integer)h.getSourceAsMap().get("age"); String sign = (String)h.getSourceAsMap().get("sign"); Object money = h.getSourceAsMap().get("money"); //高亮數據 String description = highlightField.getFragments()[0].toString(); Student studentHL = new Student(); studentHL.setDescription(description); studentHL.setStuId(Long.parseLong(stuId.toString())); studentHL.setName(name); studentHL.setAge(age); studentHL.setSign(sign); studentHL.setMoney(Float.parseFloat(money.toString())); stuHighlight.add(studentHL); } if(!stuHighlight.isEmpty()){ return new AggregatedPageImpl<>((List<T>) stuHighlight); } return null; } @Override public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) { return null; } }); System.out.println("總分頁數:" + pageStu.getTotalPages()); List<Student> stuList = pageStu.getContent(); for(Student student : stuList){ System.out.println(student); } }
返回結果如下
總分頁數:1 Student{stuId=1000, name='Nick0', age=20, money=18.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 0'} Student{stuId=1001, name='Nick1', age=21, money=19.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 1'}
9、排序
查詢結果以money進行降序
@Test public void sortStuDoc(){ String preTag = "<font color='red'>"; String postTag = "</font>"; Pageable pageable = PageRequest.of(0,10); //查詢結果以money進行排序 SortBuilder sortBuilder = new FieldSortBuilder("money") .order(SortOrder.DESC); SearchQuery query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("description","a teacher")) .withHighlightFields(new HighlightBuilder.Field("description").preTags(preTag).postTags(postTag)) .withSort(sortBuilder) .withPageable(pageable).build(); AggregatedPage<Student> pageStu = esTemplate.queryForPage(query, Student.class, new SearchResultMapper() { @Override public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) { List<Student> stuHighlight = new ArrayList<>(); SearchHits hits = searchResponse.getHits(); for(SearchHit h: hits){ HighlightField highlightField = h.getHighlightFields().get("description"); Integer stuId = (Integer)h.getSourceAsMap().get("stuId"); String name = (String)h.getSourceAsMap().get("name"); Integer age = (Integer)h.getSourceAsMap().get("age"); String sign = (String)h.getSourceAsMap().get("sign"); Object money = h.getSourceAsMap().get("money"); //高亮數據 String description = highlightField.getFragments()[0].toString(); Student studentHL = new Student(); studentHL.setDescription(description); studentHL.setStuId(Long.parseLong(stuId.toString())); studentHL.setName(name); studentHL.setAge(age); studentHL.setSign(sign); studentHL.setMoney(Float.parseFloat(money.toString())); stuHighlight.add(studentHL); } if(!stuHighlight.isEmpty()){ return new AggregatedPageImpl<>((List<T>) stuHighlight); } return null; } @Override public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) { return null; } }); System.out.println("總分頁數:" + pageStu.getTotalPages()); List<Student> stuList = pageStu.getContent(); for(Student student : stuList){ System.out.println(student); } }
返回如下:
總分頁數:1 Student{stuId=1004, name='Nick4', age=24, money=22.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 4'} Student{stuId=1003, name='Nick3', age=23, money=21.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 3'} Student{stuId=1002, name='Nick2', age=22, money=20.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 2'} Student{stuId=1001, name='Nick1', age=21, money=19.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 1'} Student{stuId=1000, name='Nick0', age=20, money=18.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 0'}
對多個字段進行排序。如對money和age進行排序