java中的ElasticSearch搜索引擎介紹。


ElasticSearch是一個基於Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放源碼發布,是當前流行的企業級搜索引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。

安裝

以windows操作系統和ES0.19.7版本為例:
①下載elasticsearch-6.4.1.zip
②直接解壓至某目錄,設置該目錄為ES_HOME 環境變量
③安裝JDK,並設置JAVA_HOME環境變量
④在windows下,運行 %ES_HOME%\bin\elasticsearch.bat即可運行

安裝插件

以head插件為例:
聯網時,直接運行%ES_HOME%\bin\plugin --install mobz/elasticsearch-head
不聯網時,下載elasticsearch-head的zipball的master包,然后運行%ES_HOME%\bin\plugin --url file:///[path-to-downloadfile] --install head,其中[path-to-downloadfile]是下載后master包的絕對路徑
安裝完成,重啟服務,在瀏覽器打開 http://localhost:9200/_plugin/head/ 即可

 ES工作原理

當ElasticSearch的節點啟動后,它會利用多播(multicast)(或者單播,如果用戶更改了配置)尋找集群中的其它節點,並與之建立連接。這個過程如下圖所示: 
這里寫圖片描述

官方代碼
1
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( 2 new HttpHost("localhost", 9200, "http"))); 3 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 4 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); 5 searchSourceBuilder.aggregation(AggregationBuilders.terms("top_10_states").field("state").size(10)); 6 SearchRequest searchRequest = new SearchRequest(); 7 searchRequest.indices("social-*"); 8 searchRequest.source(searchSourceBuilder); 9 SearchResponse searchResponse = client.search(searchRequest);

創建索引

 1 /**
 2      * 創建索引
 3      *
 4      * @param index
 5      * @return
 6      */
 7     public boolean createIndex(String index) {
 8         if (!isIndexExist(index)) {
 9             logger.info("index is not exits!");
10         }
11         CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet();
12         logger.info("success to create index " + indexresponse.isAcknowledged());
13 
14         return indexresponse.isAcknowledged();
15     }

刪除索引

 1 /**
 2      * 刪除索引
 3      *
 4      * @param index
 5      * @return
 6      */
 7     public boolean deleteIndex(String index) {
 8         if (!isIndexExist(index)) {
 9             logger.info("index is not exits!");
10         }
11         DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();
12         if (dResponse.isAcknowledged()) {
13             logger.info("delete index " + index + "  successfully!");
14         } else {
15             logger.info("fail to delete index " + index);
16         }
17         return dResponse.isAcknowledged();
18     }

判斷

 1 /**
 2      * 判斷索引是否存在
 3      *
 4      * @param index
 5      * @return
 6      */
 7     public boolean isIndexExist(String index) {
 8         IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();
 9         if (inExistsResponse.isExists()) {
10             logger.info("index [" + index + "] is exist!");
11         } else {
12             logger.info("index [" + index + "] is not exist!");
13         }
14         return inExistsResponse.isExists();
15     }
  1  /**
  2      * 通過ID獲取數據
  3      *
  4      * @param index  索引,類似數據庫
  5      * @param type   類型,類似表
  6      * @param id     數據ID
  7      * @param fields 需要顯示的字段,逗號分隔(缺省為全部字段)
  8      * @return
  9      */
 10     public Map<String, Object> searchDataById(String index, String type, String id, String fields) {
 11         GetRequestBuilder getRequestBuilder = client.prepareGet(index, type, id);
 12         if (StringUtils.isNotEmpty(fields)) {
 13             getRequestBuilder.setFetchSource(fields.split(","), null);
 14         }
 15         GetResponse getResponse =  getRequestBuilder.execute().actionGet();
 16         return getResponse.getSource();
 17     }
 18 
 19     /**
 20      * 使用分詞查詢
 21      *
 22      * @param index    索引名稱
 23      * @param type     類型名稱,可傳入多個type逗號分隔
 24      * @param fields   需要顯示的字段,逗號分隔(缺省為全部字段)
 25      * @param matchStr 過濾條件(xxx=111,aaa=222)
 26      * @return
 27      */
 28     public List<Map<String, Object>> searchListData(String index, String type, String fields, String matchStr) {
 29         return searchListData(index, type, 0, 0, null, fields, null, false, null, matchStr);
 30     }
 31 
 32     /**
 33      * 使用分詞查詢
 34      *
 35      * @param index       索引名稱
 36      * @param type        類型名稱,可傳入多個type逗號分隔
 37      * @param fields      需要顯示的字段,逗號分隔(缺省為全部字段)
 38      * @param sortField   排序字段
 39      * @param matchPhrase true 使用,短語精准匹配
 40      * @param matchStr    過濾條件(xxx=111,aaa=222)
 41      * @return
 42      */
 43     public List<Map<String, Object>> searchListData(String index, String type, String fields, String sortField, boolean matchPhrase, String matchStr) {
 44         return searchListData(index, type, 0, 0, null, fields, sortField, matchPhrase, null, matchStr);
 45     }
 46 
 47 
 48     /**
 49      * 使用分詞查詢
 50      *
 51      * @param index          索引名稱
 52      * @param type           類型名稱,可傳入多個type逗號分隔
 53      * @param size           文檔大小限制
 54      * @param fields         需要顯示的字段,逗號分隔(缺省為全部字段)
 55      * @param sortField      排序字段
 56      * @param matchPhrase    true 使用,短語精准匹配
 57      * @param highlightField 高亮字段
 58      * @param matchStr       過濾條件(xxx=111,aaa=222)
 59      * @return
 60      */
 61     public List<Map<String, Object>> searchListData(String index, String type, Integer size, String fields, String sortField, boolean matchPhrase, String highlightField, String matchStr) {
 62         return searchListData(index, type, 0, 0, size, fields, sortField, matchPhrase, highlightField, matchStr);
 63     }
 64 
 65 
 66     /**
 67      * 使用分詞查詢
 68      *
 69      * @param index          索引名稱
 70      * @param type           類型名稱,可傳入多個type逗號分隔
 71      * @param startTime      開始時間
 72      * @param endTime        結束時間
 73      * @param size           文檔大小限制
 74      * @param fields         需要顯示的字段,逗號分隔(缺省為全部字段)
 75      * @param sortField      排序字段
 76      * @param matchPhrase    true 使用,短語精准匹配
 77      * @param highlightField 高亮字段
 78      * @param matchStr       過濾條件(xxx=111,aaa=222)
 79      * @return
 80      */
 81     public List<Map<String, Object>> searchListData(String index, String type, long startTime, long endTime, Integer size, String fields, String sortField, boolean matchPhrase, String highlightField, String matchStr) {
 82         SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
 83         if (StringUtils.isNotEmpty(type)) {
 84             searchRequestBuilder.setTypes(type.split(","));
 85         }
 86         BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
 87         
 88         if (startTime > 0 && endTime > 0) {
 89             boolQuery.must(QueryBuilders.rangeQuery("processTime")
 90                     .format("epoch_millis")
 91                     .from(startTime)
 92                     .to(endTime)
 93                     .includeLower(true)
 94                     .includeUpper(true));
 95         }
 96 
 97         //搜索的的字段
 98         if (StringUtils.isNotEmpty(matchStr)) {
 99             for (String s : matchStr.split(",")) {
100                 String[] ss = s.split("=");
101                 if (ss.length > 1) {
102                     if (matchPhrase == Boolean.TRUE) {
103                         boolQuery.must(QueryBuilders.matchPhraseQuery(s.split("=")[0], s.split("=")[1]));
104                     } else {
105                         boolQuery.must(QueryBuilders.matchQuery(s.split("=")[0], s.split("=")[1]));
106                     }
107                 }
108             }
109         }
110 
111         // 高亮(xxx=111,aaa=222)
112         if (StringUtils.isNotEmpty(highlightField)) {
113             HighlightBuilder highlightBuilder = new HighlightBuilder();
114 
115             //highlightBuilder.preTags("<span style='color:red' >");//設置前綴
116             //highlightBuilder.postTags("</span>");//設置后綴
117 
118             // 設置高亮字段
119             highlightBuilder.field(highlightField);
120             searchRequestBuilder.highlighter(highlightBuilder);
121         }
122         
123         searchRequestBuilder.setQuery(boolQuery);
124         
125         if (StringUtils.isNotEmpty(fields)) {
126             searchRequestBuilder.setFetchSource(fields.split(","), null);
127         }
128         searchRequestBuilder.setFetchSource(true);
129 
130         if (StringUtils.isNotEmpty(sortField)) {
131             searchRequestBuilder.addSort(sortField, SortOrder.DESC);
132         }
133 
134         if (size != null && size > 0) {
135             searchRequestBuilder.setSize(size);
136         }
137 
138         //打印的內容 可以在 Elasticsearch head 和 Kibana  上執行查詢
139 //        logger.info("\n{}", searchRequestBuilder);
140 
141         SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
142 
143         long totalHits = searchResponse.getHits().totalHits;
144         long length = searchResponse.getHits().getHits().length;
145 
146 //        logger.info("共查詢到[{}]條數據,處理數據條數[{}]", totalHits, length);
147 
148         if (searchResponse.status().getStatus() == 200) {
149             // 解析對象
150             return setSearchResponse(searchResponse, highlightField);
151         }
152         return null;
153     }
154 
155     /**
156      * 使用分詞查詢,並分頁
157      *
158      * @param index          索引名稱
159      * @param type           類型名稱,可傳入多個type逗號分隔
160      * @param currentPage    當前頁
161      * @param pageSize       每頁顯示條數
162      * @param startTime      開始時間
163      * @param endTime        結束時間
164      * @param fields         需要顯示的字段,逗號分隔(缺省為全部字段)
165      * @param sortField      排序字段
166      * @param matchPhrase    true 使用,短語精准匹配
167      * @param highlightField 高亮字段
168      * @param matchStr       過濾條件(xxx=111,aaa=222)
169      * @return
170      */
171     public EsPage searchDataPage(String index, String type, int currentPage, int pageSize, long startTime, long endTime, String fields, String sortField, boolean matchPhrase, String highlightField, String matchStr) {
172         SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
173         if (StringUtils.isNotEmpty(type)) {
174             searchRequestBuilder.setTypes(type.split(","));
175         }
176         searchRequestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH);
177 
178         // 需要顯示的字段,逗號分隔(缺省為全部字段)
179         if (StringUtils.isNotEmpty(fields)) {
180             searchRequestBuilder.setFetchSource(fields.split(","), null);
181         }
182 
183         //排序字段
184         if (StringUtils.isNotEmpty(sortField)) {
185             searchRequestBuilder.addSort(sortField, SortOrder.DESC);
186         }
187 
188         BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
189 
190         if (startTime > 0 && endTime > 0) {
191             boolQuery.must(QueryBuilders.rangeQuery("@timestamp")
192                     .format("epoch_millis")
193                     .from(startTime)
194                     .to(endTime)
195                     .includeLower(true)
196                     .includeUpper(true));
197         }
198 
199         // 查詢字段
200         if (StringUtils.isNotEmpty(matchStr)) {
201             for (String s : matchStr.split(",")) {
202                 String[] ss = s.split("=");
203                 if (ss.length > 1) {
204                     if (matchPhrase == Boolean.TRUE) {
205                         boolQuery.must(QueryBuilders.matchPhraseQuery(s.split("=")[0], s.split("=")[1]));
206                     } else {
207                         boolQuery.must(QueryBuilders.matchQuery(s.split("=")[0], s.split("=")[1]));
208                     }
209                 }
210             }
211         }
212 
213         // 高亮(xxx=111,aaa=222)
214         if (StringUtils.isNotEmpty(highlightField)) {
215             HighlightBuilder highlightBuilder = new HighlightBuilder();
216 
217             //highlightBuilder.preTags("<span style='color:red' >");//設置前綴
218             //highlightBuilder.postTags("</span>");//設置后綴
219 
220             // 設置高亮字段
221             highlightBuilder.field(highlightField);
222             searchRequestBuilder.highlighter(highlightBuilder);
223         }
224 
225         searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
226         searchRequestBuilder.setQuery(boolQuery);
227 
228         // 分頁應用
229         searchRequestBuilder.setFrom(currentPage).setSize(pageSize);
230 
231         // 設置是否按查詢匹配度排序
232         searchRequestBuilder.setExplain(true);
233 
234         //打印的內容 可以在 Elasticsearch head 和 Kibana  上執行查詢
235 //        logger.info("\n{}", searchRequestBuilder);
236 
237         // 執行搜索,返回搜索響應信息
238         SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
239 
240         long totalHits = searchResponse.getHits().totalHits;
241         long length = searchResponse.getHits().getHits().length;
242 
243 //        logger.debug("共查詢到[{}]條數據,處理數據條數[{}]", totalHits, length);
244 
245         if (searchResponse.status().getStatus() == 200) {
246             // 解析對象
247             List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highlightField);
248 
249             return new EsPage(currentPage, pageSize, (int) totalHits, sourceList);
250         }
251         return null;
252     }
253 
254     /**
255      * 高亮結果集 特殊處理
256      *
257      * @param searchResponse
258      * @param highlightField
259      */
260     private List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {
261         List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>();
262         StringBuffer stringBuffer = new StringBuffer();
263 
264         for (SearchHit searchHit : searchResponse.getHits().getHits()) {
265             searchHit.getSource().put("id", searchHit.getId());
266 
267             if (StringUtils.isNotEmpty(highlightField)) {
268 
269                 System.out.println("遍歷 高亮結果集,覆蓋 正常結果集" + searchHit.getSource());
270                 Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments();
271 
272                 if (text != null) {
273                     for (Text str : text) {
274                         stringBuffer.append(str.string());
275                     }
276                     //遍歷 高亮結果集,覆蓋 正常結果集
277                     searchHit.getSource().put(highlightField, stringBuffer.toString());
278                 }
279             }
280             sourceList.add(searchHit.getSource());
281         }
282         return sourceList;
283     }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM