基於elasticSearch實現自動補全

基於elasticSearch實現自動補全

整體流程

  1. 添加索引,並單獨寫一個字節點用來實現自動補全,並設置類型爲completion
PUT search_index
 {
        "mappings": {
            "properties": {
                "fileName": {
                    "type": "text",
                    "analyzer": "ik_max_word",
                    "fields": {
                        "suggest": {
                            "type": "completion",
                            "analyzer": "ik_max_word"
                        }
                    }
                },
                "path": {
                    "type": "keyword",
                    "index": false
                }
            }
        }
    }

  1. 插入數據
POST /search_index/_doc
{
    "fileName":"四川成都市龍泉驛生態環境局龍泉驛區3D氣溶膠雷達監控採購項目的中標公告"
}
POST /search_index/_doc
{
    "fileName":"氣溶膠雷達租賃服務報價清單"
}
POST /search_index/_doc
{
    "fileName":"四川省遂寧市安居生態環境局臭氧在線監測預警系統採購項目競爭性磋商終止(廢標)公告"
}
  1. 實現搜索補全
POST /search_index/_search
{
  "suggest": {
    "my_suggest_document": {
      "prefix": "四",
      "completion": {
        "field": "fileName.suggest"
      }
    }
  }
}

JAVA基於RestHighLevelClient客戶端的實現

  1. 構建配置客戶端連接

    @Configuration
    @EnableElasticsearchRepositories
    public class ElasticsearchConfiguration extends AbstractElasticsearchConfiguration {
    
    
        @Override
        @Bean
        public RestHighLevelClient elasticsearchClient() {
    
            final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                    .connectedTo("192.168.15.207:9200")
    
                    //.withConnectTimeout(Duration.ofSeconds(5))
                    //.withSocketTimeout(Duration.ofSeconds(3))
                    //.useSsl()
                    //.withDefaultHeaders(defaultHeaders)
                    //.withBasicAuth(username, password)
                    // ... other options
                    .build();
            return RestClients.create(clientConfiguration).rest();
        }
    
    //    @Bean
    //    public ElasticsearchRestTemplate restTemplate() throws Exception {
    //        return new ElasticsearchRestTemplate(elasticsearchClient());
    //    }
    
    }
    
    
    
  2. 配置Java bean

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Document(indexName = "search_index", type = "_doc", shards = 5, replicas = 1)
    public class DocumentPo implements Serializable {
        private static final long serialVersionUID = 3433260756083989671L;
        @Id
        public String id;
        @Field(type = FieldType.Keyword)  
       // @Field(type = FieldType.Text, analyzer = "ik_max_word")
        public String fileName;   
        @Field(index = false, type = FieldType.Keyword)
        public String compassPath;
    
    }
    
    
  3. 添加數據

    public interface DocumentRepository extends ElasticsearchRepository<DocumentPo,Long> {
    }
    
    //添加
    @Autowired
    DocumentRepository documentRepository;
    
    documentRepository.save(documentPo);
    
  4. 實現搜索

     @Autowired
        private RestHighLevelClient restHighLevelClient;
    
    @RequestMapping(value = "/by_contact",method = RequestMethod.GET)
        public Object getSearchSuggest(HttpServletRequest request, @RequestParam(value = "keyWord")String keyWord)  {
            //指定在哪個字段搜索
            String suggestField = "fileName.suggest";
            SearchRequest searchRequest = new SearchRequest("search_index");
            searchRequest.types("_doc");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder qb = QueryBuilders.boolQuery();
            SuggestionBuilder termSuggestionBuilder =SuggestBuilders.completionSuggestion(suggestField).prefix(keyWord).skipDuplicates(true).size(10);
            SuggestBuilder suggestBuilder = new SuggestBuilder();
            suggestBuilder.addSuggestion("my_suggest_document", termSuggestionBuilder );
            searchSourceBuilder.suggest(suggestBuilder);
            searchRequest.source(searchSourceBuilder);
            SearchResponse response = null;
            try {
                response = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            Suggest suggest = response.getSuggest();
            List<String> keywords = null;
            if (suggest != null) {
                keywords = new ArrayList<>();
                List<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> entries =
                        suggest.getSuggestion("my_suggest_document").getEntries();
                for (Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> entry: entries) {
                    for (Suggest.Suggestion.Entry.Option option: entry.getOptions()) {
                        String keyword = option.getText().string();
                        if (!StringUtils.isEmpty(keyword)) {
                            if (keywords.contains(keyword)) {
                                continue;
                            }
                            keywords.add(keyword);
                            if (keywords.size() >= 9) {
                                break;
                            }
                        }
                    }
                }
            }
            return keywords;
        }
    
    

多個條件的搜索

 public SearchResponse autosuggestSearch() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder qb = QueryBuilders.boolQuery();

        PrefixQueryBuilder namePQBuilder = QueryBuilders.prefixQuery("address", "usa");
        PrefixQueryBuilder addressPQBuilder = QueryBuilders.prefixQuery("address", "usa");
        qb.should(namePQBuilder);
        qb.should(addressPQBuilder); //Similarly add more fields prefix queries.
        sourceBuilder.query(qb);

        SearchRequest searchRequest = new SearchRequest("employee").source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("Search JSON query \n" + searchRequest.source().toString()); //Generated ES search JSON.
        return searchResponse;
    }

參考網址

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html

https://stackoverflow.com/questions/60397369/elasticsearch-7-6-3-java-highlevel-rest-client-auto-suggest-across-multiple-fi

https://stackoverflow.com/questions/54399859/completion-suggester-in-elasticsearch-6-5-4-with-java-rest-client-api?answertab=votes#tab-top

https://stackoverflow.com/questions/48657904/how-to-write-rest-high-level-client-query-for-prefix-suggestion/50707641

https://blog.csdn.net/jonkee/article/details/115421810

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章