ElasticSearch系列四 CURD
阿新 • • 發佈:2020-02-29
1: ES 類似JPA操作
1.1 編寫實體類
1.2 編寫對映檔案 xxx.json
1.3編寫repository繼承 ElasticSearchrepository
1.4 編寫admin 的CRUD
2: 使用ElasticSearchtemplate 對索引操作
2.1 對索引的各類操作
3: 高階查詢
配置application
##es 單個ES地址 #spring.data.elasticsearch.cluster-nodes= ## 設定ES多個地址 spring.data.elasticsearch.client.reactive.endpoints=[http://localhost:9200] ## 開啟repositories spring.data.elasticsearch.repositories.enabled=true #spring.data.elasticsearch.client.reactive.connection-timeout= #spring.data.elasticsearch.client.reactive.password= #spring.data.elasticsearch.client.reactive.socket-timeout= #spring.data.elasticsearch.client.reactive.username= ##es 單個ES地址 #spring.data.elasticsearch.cluster-nodes= ## 設定ES多個地址 spring.data.elasticsearch.client.reactive.endpoints=[http://localhost:9200] ## 開啟repositories spring.data.elasticsearch.repositories.enabled=true #spring.data.elasticsearch.client.reactive.connection-timeout= #spring.data.elasticsearch.client.reactive.password= #spring.data.elasticsearch.client.reactive.socket-timeout= #spring.data.elasticsearch.client.reactive.username=
pom依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
1: ES 類似JPA操作
1.1 編寫實體類
// indexName: 索引名稱 type: 執行資料庫型別的表 @Document(indexName = "esadmin",type = "admin") @Mapping(mappingPath = "admin_es.json") //指向對映檔案 public class Admin { @Id private Long id; private String username; private String password; private String loveThings; // getter setter 方法
1.2 編寫對映檔案 xxx.json
{ "properties": { "id": { "type": "long" }, "username": { "type": "string", "index": "not_analyzed" }, "password": { "type": "string", "index": "not_analyzed" }, "loveThings": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" } } }
1.3編寫repository繼承 ElasticSearchrepository
@Repository public interface AdminRepository extends ElasticsearchRepository<Admin,Long> { }
1.4 編寫admin 的CRUD
@RestController public class AdminController { @Autowired private AdminRepository adminRepository; // http://localhost:8080/saveOrUpdate /** * send data * { * "username":"dgw3", * "password":"root", * "loveThings":"postman(二):使用postman傳送get or post請" * } */ @PostMapping("saveOrUpdate") public String saveOrUpdate(@RequestBody Admin admin){ if(admin.getId()==null){ admin.setId(System.currentTimeMillis()); } adminRepository.save(admin); return "儲存成功"; } //http://localhost:8080/delete?id=1582946734759 @GetMapping("delete") public String delete(Long id){ try { adminRepository.deleteById(id); } catch (Exception e) { e.printStackTrace(); return "刪除失敗"; } return "刪除成功"; } //http://localhost:8080/findById?id=1582946734759 @GetMapping("findById") public Admin findById(long id){ Optional<Admin> admin = adminRepository.findById(id); if(admin.isPresent()){ return admin.get(); }else{ return null; } } //http://localhost:8080/findAll @GetMapping("findAll") public Iterable<Admin> findAll(){ return adminRepository.findAll(); } }
2: 使用ElasticSearchtemplate 對索引操作
2.1 對索引的各類操作
@RestController public class ElasticOperationControler { @Autowired private ElasticsearchTemplate elasticsearchTemplate; @GetMapping("createIndex") public boolean createIndex(String indexName){ return elasticsearchTemplate.createIndex(indexName); } @GetMapping("deleteIndex") public boolean deleteIndex(String indexName){ return elasticsearchTemplate.deleteIndex(indexName); } @GetMapping("indexIsExist") public boolean indexIsExist(String indexName){ return elasticsearchTemplate.indexExists(indexName); } @GetMapping("typeIsExist") public boolean typeIsExist(String indexName,String type){ return elasticsearchTemplate.typeExists(indexName,type); } @GetMapping("getMapping") public Map getMapping(String indexName, String type){ return elasticsearchTemplate.getMapping(indexName,type); } @GetMapping("getSetting") public Map getSetting(String indexName){ return elasticsearchTemplate.getSetting(indexName); } }
3: 高階查詢
查詢步驟:
- QueryBuilders 構建查詢關鍵詞
- SortBuilders 構建對關鍵字的排序
- NativeSearchQueryBuilder 對前兩個條件進行封裝,
- Repository : 進行查詢
@RestController public class SearchController { @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Autowired private ArticleRepository articleRepository; //1.不分詞查詢:查詢articleContent帶有你好 或者 articleName帶有你好的文章列表,並且按照readCount倒敘排序 //http://localhost:8080/query1?keyword=你好 @GetMapping("query1") public List<Article> query1(String keyword) { BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); BoolQueryBuilder articleContent = boolQuery.should(QueryBuilders.termQuery("articleContent", keyword)); BoolQueryBuilder articleName = boolQuery.should(QueryBuilders.termQuery("articleName", keyword)); FieldSortBuilder order = SortBuilders.fieldSort("readCount").order(SortOrder.DESC); NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); nativeSearchQueryBuilder.withQuery(articleContent); nativeSearchQueryBuilder.withQuery(articleName); nativeSearchQueryBuilder.withSort(order); NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build(); Page<Article> articles = articleRepository.search(searchQuery); if (articles != null) { return articles.getContent(); } else { return null; } } //2.不分詞查詢:查詢articleContent帶有我們 或者 你好 並且authorAge在20歲以下的文章列表,並且按照readCount倒敘排序 //http://localhost:8080/query11?keyword=你好,我們 @GetMapping("query2") public List<Article> query2(String... keyword) { BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(QueryBuilders.termsQuery("articleContent", keyword)); boolQueryBuilder.must(QueryBuilders.rangeQuery("authorAge").lt(20)); FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("readCount").order(SortOrder.DESC); NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); nativeSearchQueryBuilder.withQuery(boolQueryBuilder); nativeSearchQueryBuilder.withSort(fieldSortBuilder); NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build(); Page<Article> page = articleRepository.search(nativeSearchQuery); if (page != null) { return page.getContent(); } else { return null; } } //3.分詞查詢:經過分詞,查詢articleContent帶有你好節日一詞分詞後的文章列表,並且按照authorAge倒敘排序 //http://localhost:8080/query12?keyword=你好節日 @GetMapping("query3") public List<Article> query3(String keyword) { BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.should(QueryBuilders.matchQuery("articleContent", keyword)); FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("authorAge").order(SortOrder.DESC); NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); nativeSearchQueryBuilder.withQuery(boolQueryBuilder); nativeSearchQueryBuilder.withSort(fieldSortBuilder); NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build(); Page<Article> page = articleRepository.search(nativeSearchQuery); if (page != null) { return page.getContent(); } else { return null; } } //4.分頁分詞查詢:經過分詞,查詢articleContent帶有你好節日一詞分詞後的文章列表,並且按照authorAge倒敘排序 //http://localhost:8080/query13?keyword=你好節日&pageNum=1&pageSize=5 @GetMapping("query4") public Page<Article> query4(String keyword, Integer pageNum, Integer pageSize) { BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.should(QueryBuilders.matchQuery("articleContent", keyword)); FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("authorAge").order(SortOrder.DESC); PageRequest pageRequest = new PageRequest(pageNum, pageSize); NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); nativeSearchQueryBuilder.withQuery(boolQueryBuilder); nativeSearchQueryBuilder.withSort(fieldSortBuilder); nativeSearchQueryBuilder.withPageable(pageRequest); NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build(); Page<Article> page = articleRepository.search(nativeSearchQuery); if (page != null) { return page; } else { return null; } } //5.分頁分詞查詢:經過分詞,查詢articleContent帶有你好節日一詞分詞後的文章列表,並且按照authorAge倒敘排序,並且對匹配到的詞語設定為高亮 //http://localhost:8080/query14?keyword=你好節日&pageNum=1&pageSize=5&fieldNames=articleContent,articleName @GetMapping("query5") public Map<String, Object> query5(String keyword, Integer pageNum, Integer pageSize, String... fieldNames) { //定義返回的map Map<String, Object> returnMap = new HashMap<String,Object>(); // 不使用預設的分詞器 直接操控索引 //構建請求構建器,設定查詢索引 SearchRequestBuilder builder = elasticsearchTemplate.getClient().prepareSearch("testes"); //構建查詢構建器,設定分詞器(如果沒設定使用預設) QueryBuilder matchQuery = QueryBuilders.multiMatchQuery(keyword, fieldNames).analyzer("ik_max_word"); //構建高亮構建器 HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(false); highlightBuilder.preTags("<span style=\"color:red\">"); highlightBuilder.postTags("</span>"); //將高亮構建器,查詢構建器,分頁引數設定到請求構建器內 builder.highlighter(highlightBuilder); builder.setQuery(matchQuery); builder.setFrom((pageNum - 1) * pageSize); builder.setSize(pageNum * pageSize); builder.setSize(pageSize); //執行搜尋,返回搜尋響應資訊 SearchResponse searchResponse = builder.get(); SearchHits searchHits = searchResponse.getHits(); //總命中數 long total = searchHits.getTotalHits(); returnMap.put("count", total); //將高亮欄位封裝到返回map SearchHit[] hits = searchHits.getHits(); List<Map<String,Object>> list = new ArrayList<>(); Map<String,Object> map; for(SearchHit searchHit : hits){ map = new HashMap<>(); map.put("data",searchHit.getSourceAsMap()); Map<String,Object> hitMap = new HashMap<>(); searchHit.getHighlightFields().forEach((k,v) -> { String hight = ""; for(Text text : v.getFragments()){ hight += text.string(); } hitMap.put(v.getName(),hight); }); map.put("highlight",hitMap); list.add(map); } returnMap.put("dataList", list); return returnMap; }