1. 环境配置
pom.xml
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.8.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.8.0</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>7.8.0</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>7.8.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> </dependency>
application.yaml
# 项目名 server: servlet: context-path: /es_demo spring: elasticsearch: uris: localhost:9200 connection-timeout: 5s socket-timeout: 30s
2. ElasticSearch配置类
@Configuration public class ElasticsearchConfig { @Bean public RestHighLevelClient restHighLevelClient(){ RestHighLevelClient client=new RestHighLevelClient( RestClient.builder( new HttpHost("192.168.4.221",9200,"http") ) ); return client; } }
3. 文档Document 对象
@Document(indexName="myuser") public class User { @Id private Integer id; @Field(type = FieldType.Auto)//自动检测类型 private Integer age; @Field(type = FieldType.Keyword)//手动设置为keyword 但同时也就不能分词 private String name; @Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_max_word")//设置为text 可以分词 private String info; public User(){} public User(Integer id, Integer age, String name, String info) { this.id = id; this.age = age; this.name = name; this.info = info; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Override public String toString() { return "User{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + ", info='" + info + '\'' + '}'; } }
3. service
@Service @Repository // crud: create retrive update delete public interface EsUserService extends ElasticsearchRepository<User,Integer> { List<User> findByName(String userName); List<User> findByInfo(String userInfo); } public interface EsUserService2 { public Map<String,Object> getUserList(String name, String info, Integer pageNum); } @Service public class EsUserServiceImpl implements EsUserService2 { @Autowired private ElasticsearchRestTemplate restTemplate; @Override public Map<String,Object> getUserList(String name, String info, Integer pageNum) { if(pageNum == null) pageNum = 1; Pageable pageable= PageRequest.of(pageNum-1,3); BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder(); if(name!=null){ QueryBuilder queryBuilder= QueryBuilders.queryStringQuery(name); boolQueryBuilder.must(queryBuilder); }else{ if(info!=null) { boolQueryBuilder.must(new MatchQueryBuilder("info", info)); } } SortBuilder sortBuilder= SortBuilders.scoreSort(); FieldSortBuilder age = SortBuilders.fieldSort("age"); sortBuilder.order(SortOrder.DESC); //构建高亮查询 /* NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(boolQueryBuilder) .withHighlightFields( new HighlightBuilder.Field("info"), new HighlightBuilder.Field("name")) .withHighlightBuilder(new HighlightBuilder() .preTags("<span style='color:red'>") .postTags("</span>")) .build(); */ NativeSearchQueryBuilder builder=new NativeSearchQueryBuilder(); NativeSearchQuery query=builder .withQuery(boolQueryBuilder) .withPageable(pageable) .withSort(sortBuilder) .withHighlightFields( new HighlightBuilder.Field("info"), new HighlightBuilder.Field("name")) .withHighlightBuilder(new HighlightBuilder() .preTags("<span style='color:red'>") .postTags("</span>")) .build(); SearchHits<User> search = restTemplate.search(query, User.class); List<User> userList=new ArrayList<>(); for(SearchHit<User> searchHit:search){ //高亮内容 Map<String ,List<String>> highlightFields = searchHit.getHighlightFields(); //将高亮的内容填充到content中 String highLightName = highlightFields.get("name") ==null ?searchHit.getContent().getName() :highlightFields.get("name").get(0); String highLightInfo = highlightFields.get("info") ==null ?searchHit.getContent().getName() :highlightFields.get("info").get(0); searchHit.getContent().setName(highLightName ); searchHit.getContent().setInfo(highLightInfo); //放到实体类中 userList.add(searchHit.getContent()); /* User user1=user.getContent(); userList.add(user1); System.out.println(user1);*/ } SearchPage<User> searchPage= SearchHitSupport.searchPageFor(search,query.getPageable()); //总记录数 long totalElements=searchPage.getTotalElements(); //总页数 int totalPages=searchPage.getTotalPages(); //当前页数 int currentPage=searchPage.getPageable().getPageNumber(); System.out.println(currentPage); Map<String,Object> map=new HashMap<>(); map.put("totalElements",totalElements); map.put("totalPages",totalPages); map.put("currentPage",currentPage); map.put("user",userList); return map; } }
4. controller
@RestController public class EsUserController { @Autowired private ElasticsearchRestTemplate restTemplate; @Autowired private EsUserService userService; @Autowired private EsUserService2 userService2; private String[] names = {"诸葛亮","曹操","李白","韩信","赵云","小乔","狄仁杰","李四","诸小明","王五"}; private String[] infos = {"我来自中国的一个小乡村,地处湖南省","我来自中国的一个大城市,名叫上海,人们称作魔都" ,"我来自东北,家住大囤里,一口大碴子话"}; @GetMapping("saveUser") public String saveUser(){ Random random = new Random(); List<User> users = new ArrayList<>(); /* for(int i =0;i<20;i++){ User user = new User(i,random.nextInt(40)+i,names[random.nextInt(9)] , infos[random.nextInt(2)] ); users.add(user); }*/ User user1 = new User(20,21,"上海的小李","上周的天气不错,海边风大"); User user2 = new User(21,21,"上海的小王","昨天的天气不错,海边风大"); User user3 = new User(22,21,"浙江的老王","昨天的天气不错,海边风大"); User user4 = new User(23,21,"苏州的小赵","上周的天气不错,海边风大"); users.add(user1); users.add(user2); users.add(user3); users.add(user4); Iterable<User> users1 = userService.saveAll(users); return "save successfully"; } @GetMapping("getDataById/{id}") public Optional<User> getDataById(@PathVariable("id") Integer id){ Optional<User> user = userService.findById(id); System.out.println("get by id user:" + user); return user; } // 分页查询 @GetMapping("getAllDataByPage") public Page<User> getAllDataByPage(){ Pageable page = PageRequest.of(0,10, Sort.Direction.ASC,"id"); Page<User> allUser =userService.findAll(page); System.out.println("getAllDataByPage:" + allUser); return allUser; } //根据名字查询 @GetMapping("getDataByName/{name}") public List<User> getDataByName(@PathVariable("name") String name){ return userService.findByName(name); } @GetMapping("getDataByNameandInfo/{info}") //根据名字查询 public List<User> getDataByInfo(@PathVariable("info") String info){ return userService.findByInfo(info); } // 查询高亮显示 @GetMapping("getHighByUser") public List<User> getHighByUser(@PathParam("kw") String kw){ System.out.println("kw = " + kw); //根据一个值查询多个字段,并高亮显示,这里的查询是取并集, //即多个字段只要有一个字段满足即可 //需要查询的字段 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery() .should(QueryBuilders.matchQuery("info",kw)) .should(QueryBuilders.matchQuery("name",kw)); //构建高亮查询 NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(boolQueryBuilder) .withHighlightFields( new HighlightBuilder.Field("info"), new HighlightBuilder.Field("name")) .withHighlightBuilder(new HighlightBuilder() .preTags("<span style='color:yellow'>") .postTags("</span>")) .build(); //查询 SearchHits<User> search = restTemplate.search(searchQuery,User.class); // SearchHits<User> ==== for(...user ) -- high light name : old name , high light info : old info // new user ---- List<User> //得到查询返回的内容 List<SearchHit<User>> searchHits = search.getSearchHits();//getSearchHits(); //设置一个最后需要返回的实体类集合 List<User> userList = new ArrayList<>(); for(SearchHit<User> searchHit:searchHits){ //高亮内容 Map<String ,List<String>> highlightFields = searchHit.getHighlightFields(); //将高亮的内容填充到content中 String name = highlightFields.get("name") ==null ?searchHit.getContent().getName() :highlightFields.get("name").get(0); String info = highlightFields.get("info") ==null ?searchHit.getContent().getName() :highlightFields.get("info").get(0); searchHit.getContent().setName(name ); searchHit.getContent().setInfo(info); //放到实体类中 userList.add(searchHit.getContent()); } return userList; } @GetMapping("getHighByPage/{name}/{info}/{pageNum}") public Map<String,Object> getHighByPage(@PathVariable("name") String name, @PathVariable("info") String info , @PathVariable("pageNum")Integer pageNum){ return userService2.getUserList(name,info,pageNum); } }