springboot 에서 Elastic Search 를 사용 하 는 상세 한 튜 토리 얼

21483 단어 springbootlasticSearch
새 항목
이번 ElasticSearch 와 의 통합 에 사용 할 springboot 프로젝트springboot_es를 새로 만 듭 니 다.다음 그림 입 니 다.
在这里插入图片描述
도입 의존
우리 의pom.xml를 수정 하고 가입spring-boot-starter-data-elasticsearch

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
프로필 작성
Elastic Search 는 7.x 버 전부터 TransportClient 를 약화 시 키 고 심지어 8.x 버 전에 서 버 렸 기 때문에 spring data elasticsearch 는 rest 클 라 이언 트RestHingLevelClient(포트 번호 사용 9200)와 인터페이스ElasticSearchRespositoy를 사용 하 는 것 을 추천 합 니 다.
  • RestHigh LevelClient 가 더 강하 고 유연 하지만 우호 적 인 조작 대상
  • ElasticSearchRepository 대상 조작 우호
  • 우선 프로필 을 작성 하 겠 습 니 다.다음 과 같 습 니 다.
    
    /**
     * ElasticSearch Rest Client config
     * @author Christy
     * @date 2021/4/29 19:40
     **/
    @Configuration
    public class ElasticSearchRestClientConfig extends AbstractElasticsearchConfiguration{
        
      	@Override
        @Bean
        public RestHighLevelClient elasticsearchClient() {
            final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                    .connectedTo("192.168.8.101:9200")
                    .build();
            return RestClients.create(clientConfiguration).rest();
        }
    
    }
    springboot 조작 ES
     RestHigh LevelClient 방식
    위의 rest client 가 있 으 면 우 리 는 다른 곳 에 이 클 라 이언 트 를 주입 하여 Elastic Search 를 조작 할 수 있 습 니 다.저 희 는 테스트 파일 을 새로 만 들 었 습 니 다.클 라 이언 트 를 사용 하여 ElasticSearch 를 기본 으로 합 니 다.
    1.RestClient 주입
    
    /**
     * ElasticSearch Rest client  
     *
     * RestHighLevelClient    ,   ,           
     * ElasticSearchRepository       
     *
     *     rest client          
     * @Author Christy
     * @Date 2021/4/29 19:51
     **/
    @SpringBootTest
    public class TestRestClient {
        //       :      
        @Autowired
        private RestHighLevelClient restHighLevelClient;
    }
    2.문서 삽입
    
    /**
     *       
     * @author Christy
     * @date 2021/4/29 20:17
     */
    @Test
    public void testAdd() throws IOException {
        /**
          *  ES    christy  type         
          */
        IndexRequest indexRequest = new IndexRequest("christy","user","11");
        indexRequest.source("{\"name\":\"       \",\"age\":685,\"bir\":\"1685-01-01\",\"introduce\":\"                  !\"," +
                            "\"address\":\"   \"}", XContentType.JSON);
        IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(indexResponse.status());
    }
    在这里插入图片描述
    우 리 는 문서 삽입 이 성공 한 것 을 볼 수 있 습 니 다.우 리 는 kibana 에 가서 이 문 서 를 조회 할 수 있 습 니 다.
    在这里插入图片描述
    전혀 문제 없어 요.
    3.문서 삭제
    
    /**
     *       
     * @author Christy
     * @date 2021/4/29 20:18
     */
    @Test
    public void deleteDoc() throws IOException {
        //          
        DeleteRequest deleteRequest = new DeleteRequest("christy","user","rYBNG3kBRz-Sn-2f3ViU");
        DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(deleteResponse.status());
      }
    }
    在这里插入图片描述
    4.문서 업데이트
    
    /**
     *       
     * @author Christy
     * @date 2021/4/29 20:19
     */
    @Test
    public void updateDoc() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("christy","user","p4AtG3kBRz-Sn-2fMFjj");
        updateRequest.doc("{\"name\":\"     hardy\"}",XContentType.JSON);
        UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(updateResponse.status());
    }
    在这里插入图片描述
    5.문서 일괄 업데이트
    
    /**
     *     
     * @author Christy
     * @date 2021/4/29 20:42
     */
    @Test
    public void bulkUpdate() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        //   
        IndexRequest indexRequest = new IndexRequest("christy","user","13");
        indexRequest.source("{\"name\":\"       \",\"age\":985,\"bir\":\"1685-01-01\",\"introduce\":\"                \",\"address\":\"   \"}", XContentType.JSON);
        bulkRequest.add(indexRequest);
    
        //   
        DeleteRequest deleteRequest01 = new DeleteRequest("christy","user","pYAtG3kBRz-Sn-2fMFjj");
        DeleteRequest deleteRequest02 = new DeleteRequest("christy","user","uhTyGHkBExaVQsl4F9Lj");
        DeleteRequest deleteRequest03 = new DeleteRequest("christy","user","C8zCGHkB5KgTrUTeLyE_");
        bulkRequest.add(deleteRequest01);
        bulkRequest.add(deleteRequest02);
        bulkRequest.add(deleteRequest03);
    
        //   
        UpdateRequest updateRequest = new UpdateRequest("christy","user","10");
        updateRequest.doc("{\"name\":\"       \"}",XContentType.JSON);
        bulkRequest.add(updateRequest);
    
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        BulkItemResponse[] items = bulkResponse.getItems();
        for (BulkItemResponse item : items) {
          System.out.println(item.status());
        }
    }
    kibana 에서 결 과 를 조회 합 니 다.
    在这里插入图片描述
    6.문서 조회
    
    @Test
    public void testSearch() throws IOException {
        //      
        SearchRequest searchRequest = new SearchRequest("christy");
        //      
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
        searchSourceBuilder.query(QueryBuilders.matchAllQuery())//      
          .from(0)//    
          .size(10)//      
          .postFilter(QueryBuilders.matchAllQuery()) //    
          .sort("age", SortOrder.DESC);//  
    
        //      
        searchRequest.types("user").source(searchSourceBuilder);
    
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
        System.out.println("         : "+searchResponse.getHits().getTotalHits());
        System.out.println("           : "+searchResponse.getHits().getMaxScore());
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
          System.out.println(hit.getSourceAsMap());
        }
    }
    在这里插入图片描述
    ElasticSearchRepository 방식
    1.준비 작업
    ElasticSearchRepository 방식 은 주로 주해 와 인터페이스 실현 방식 을 통 해 ES 의 조작 을 실현 합 니 다.우 리 는 실체 류 에서 ES 색인 을 설정 하 는 매 핑 관 계 를 주해 한 후에 ElasticSearchRepository 인터페이스의 클래스 가 처음으로 ES 를 조작 하여 문 서 를 삽입 할 때 ES 는 필요 한 모든 것 을 자동 으로 생 성 합 니 다.그러나 이 방식 은 하 이 라이트 조 회 를 실현 할 수 없고 하 이 라이트 조 회 를 실현 하려 면 RestHigh LevelClient 만 사용 할 수 있 습 니 다.
    시작 하기 전에 우 리 는 인터페이스 방식 이 우리 에 게 제공 하 는 주석 과 기본 적 인 종 류 를 작성 하 는 것 을 익 혀 야 한다.
    1.ES 데이터 비우 기
    在这里插入图片描述
    2.주 해 를 이해 하기@Document:문서 기록 을 대표 합 니 다.indexName:색인 이름 을 지정 하 는 데 사용 합 니 다.type:색인 형식 을 지정 합 니 다.@Id:대상 의 id 와 ES 중id 맵@Field:ES 의 필드 에 대응 하 는 Mapping 을 지정 합 니 다.type:ES 에 저 장 된 형식 을 지정 합 니 다.analyzer:어떤 단어 기 를 사용 할 지 지정 합 니 다.
    3.새 실체 클래스
    
    /**
     *       : Emp      ES   json    
     * indexName:            json            :ES              
     * type     :                    
     *
     * @Author Christy
     * @Date 2021/4/29 21:22
     */
    @Data
    @Document(indexName = "christy",type = "user")
    public class User {
        @Id //      id      _id     
        private String id;
    
        //         mapping           type:            analyzer:     
        @Field(type = FieldType.Text,analyzer = "ik_max_word")
        private String name;
    
        @Field(type = FieldType.Integer)
        private Integer age;
    
        @Field(type = FieldType.Date)
        @JsonFormat(pattern = "yyyy-MM-dd")
        private Date bir;
    
        @Field(type = FieldType.Text,analyzer = "ik_max_word")
        private String content;
    
        @Field(type = FieldType.Text,analyzer = "ik_max_word")
        private String address;
    }
    4.UserRepository
    
    /**
     * @Author Christy
     * @Date 2021/4/29 21:23
     **/
    public interface 
      extends ElasticsearchRepository<User,String> {
    }
    5.TestUserRepository
    
    /**
     * @Author Christy
     * @Date 2021/4/29 21:51
     **/
    @SpringBootTest
    public class TestUserRepository {
        @Autowired
        private UserRepository userRepository;
    
    }
    2.문서 저장
    
    @Test
    public void testSaveAndUpdate(){
      User user = new User();
      // id    ,      
      user.setId(UUID.randomUUID().toString());
      user.setName("   ");
      user.setBir(new Date());
      user.setIntroduce("                ,       ,    !");
      user.setAddress("     ");
      userRepository.save(user);
    }
    在这里插入图片描述
    3.문서 수정
    
    @Test
    public void testSaveAndUpdate(){
        User user = new User();
      	//   id    
        user.setId("1666eb47-0bbf-468b-ab45-07758c741461");
        user.setName("   ");
        user.setBir(new Date());
        user.setIntroduce("    ,    。                ,       ,    !");
        user.setAddress("     ");
        userRepository.save(user);
    }
    在这里插入图片描述
    4.문서 삭제
    reposcory 인 터 페 이 스 는 기본적으로 4 가지 삭제 방식 을 제공 합 니 다.id 에 따라 삭제 하 는 것 을 보 여 줍 니 다.
    在这里插入图片描述
    
    @Test
    public void deleteDoc(){
      	userRepository.deleteById("1666eb47-0bbf-468b-ab45-07758c741461");
    }
    在这里插入图片描述
    5.기록 검색
    
    @Test
    public void testFindOne(){
        Optional<User> optional = userRepository.findById("1666eb47-0bbf-468b-ab45-07758c741461");
        System.out.println(optional.get());
    }
    在这里插入图片描述
    6.모든 것 조회
    
    @Test
    public void testFindAll(){
        Iterable<User> all = userRepository.findAll();
        all.forEach(user-> System.out.println(user));
    }
    在这里插入图片描述
    7.정렬
    
    @Test
    public void testFindAllSort(){
        Iterable<User> all = userRepository.findAll(Sort.by(Sort.Order.asc("age")));
        all.forEach(user-> System.out.println(user));
    }
    在这里插入图片描述
    8.페이지 나 누 기
    
    @Test
    public void testFindPage(){
        //PageRequest.of   1:    -1
        Page<User> search = userRepository.search(QueryBuilders.matchAllQuery(), PageRequest.of(1, 1));
        search.forEach(user-> System.out.println(user));
    }
    在这里插入图片描述
    9.사용자 정의 조회
    먼저 시 계 를 보 여 드 리 겠 습 니 다.어 지 럽 죠?¦3」∠)_
    Keyword
    Sample
    Elasticsearch Query StringAnd findByNameAndPrice {"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}} Or findByNameOrPrice {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}} Is findByName {"bool" : {"must" : {"field" : {"name" : "?"}}}} Not findByNameNot {"bool" : {"must_not" : {"field" : {"name" : "?"}}}} Between findByPriceBetween {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}} LessThanEqual findByPriceLessThan {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}} GreaterThanEqual findByPriceGreaterThan {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}} Before findByPriceBefore {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}} After findByPriceAfter {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}} Like findByNameLike {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}} StartingWith findByNameStartingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}} EndingWith findByNameEndingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}} Contains/Containing findByNameContaining {"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}} In findByNameIn (Collection<String>names) {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}} NotIn findByNameNotIn (Collection<String>names) {"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}} Near findByStoreNear Not Supported Yet ! True findByAvailableTrue {"bool" : {"must" : {"field" : {"available" : true}}}} False findByAvailableFalse {"bool" : {"must" : {"field" : {"available" : false}}}} OrderBy findByAvailable TrueOrderByNameDesc {"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}이 표 는 보기 에는 복잡 해 보이 지만,실제로는 간단 하지 않 지만,확실히 대단 하 다.우 리 는 위의 정의 에 따라 인터페이스 에서 해당 하 는 방법 을 정의 하기 만 하면 실현 을 쓰 지 않 아 도 우리 가 원 하 는 기능 을 실현 할 수 있다.
    예 를 들 어 위 에 findByName 이 있 습 니 다.아래 에 이렇게 정의 되 어 있 습 니 다.
    在这里插入图片描述
    만약 우리 가 지금 이름 에 따라 사용 자 를 조회 해 야 하 는 수요 가 있다 면,우 리 는UserRepository에서 다음 과 같은 방법 을 정의 할 수 있다.
    
    //       
    List<User> findByName(String name);
    在这里插入图片描述
    시스템 에서 제공 하 는 조회 방법findBy은 위 에서 우리 가 정의 한 방법findByName과 같은 고정 적 인 쓰기 입 니 다.그 중에서 Name 은 우리 실체 류 의 속성 명 입 니 다.이것 은 반드시 대응 해 야 합 니 다.즉,이 findByName 은name에 만 국한 되 는 것 이 아니 라 findByAddress,findByAge 등 도 할 수 있다.
    지금 findByName 으로 말 하면 당 삼장 이라는 사용 자 를 조회 해 야 합 니 다.
    
    @Test
    public void testFindByName(){
        List<User> userList = userRepository.findByName("   ");
        userList.forEach(user-> System.out.println(user));
    }
    在这里插入图片描述
    사실은 프레임 밑 에 아래 명령 을 직접 사용 하여 우리 가 실현 할 수 있 도록 도와 주 는 조회 이다.
    
    GET /christy/user/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "name":"?"
              }
            }
          ]
        }
      }
    }
    在这里插入图片描述
    10.하 이 라이트 조회
    위 에서 말 했 듯 이 ElasticSearch Repository 는 하 이 라이트 조 회 를 실현 할 수 없습니다.하 이 라이트 조 회 를 실현 하려 면 RestHigh LevelClient 방식 을 사용 해 야 합 니 다.마지막 으로 저 희 는 rest clientl 을 사용 하여 하 이 라이트 조 회 를 실현 합 니 다.
    
    @Test
    public void testHighLightQuery() throws IOException, ParseException {
        //       
        SearchRequest searchRequest = new SearchRequest("christy");
        //       
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("introduce", "  "))    //       
          .from(0)    //     (   -1)*size  
          .size(10)   //       
          .sort("age", SortOrder.DESC)    //   
          .highlighter(new HighlightBuilder().field("*").requireFieldMatch(false).preTags("<span style='color:red;'>").postTags("</span>"));  //     
        searchRequest.types("user").source(searchSourceBuilder);
    
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
        SearchHit[] hits = searchResponse.getHits().getHits();
        List<User> userList = new ArrayList<>();
        for (SearchHit hit : hits) {
          Map<String, Object> sourceAsMap = hit.getSourceAsMap();
    
          User user = new User();
          user.setId(hit.getId());
          user.setAge(Integer.parseInt(sourceAsMap.get("age").toString()));
          user.setBir(new SimpleDateFormat("yyyy-MM-dd").parse(sourceAsMap.get("bir").toString()));
          user.setIntroduce(sourceAsMap.get("introduce").toString());
          user.setName(sourceAsMap.get("name").toString());
          user.setAddress(sourceAsMap.get("address").toString());
    
          Map<String, HighlightField> highlightFields = hit.getHighlightFields();
          if(highlightFields.containsKey("name")){
            user.setName(highlightFields.get("name").fragments()[0].toString());
          }
    
          if(highlightFields.containsKey("introduce")){
            user.setIntroduce(highlightFields.get("introduce").fragments()[0].toString());
          }
    
          if(highlightFields.containsKey("address")){
            user.setAddress(highlightFields.get("address").fragments()[0].toString());
          }
    
          userList.add(user);
        }
    
        userList.forEach(user -> System.out.println(user));
    }
    在这里插入图片描述
    ElasticSearch 가 springboot 에서 사용 하 는 상세 한 튜 토리 얼 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 springboot 에서 ElasticSearch 를 사용 하 는 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기