elasticsearch demo詳解
功能列表
一、用spring boot搭建的後端框架
二、頁面渲染在後端,用的是thymeleaf模版引擎
三、前端使用angularJs實現數據視圖的雙向綁定,並且用的angular自帶的resource模塊請求restful接口
四、提供了提交數據的頁面和相關接口
五、提供了多條件查詢的頁面和相關接口
六、提供了查詢結果匹配高亮顯示,分頁查詢等功能
項目目錄一覽
項目目錄一覽
一、用spring boot搭建的後端框架
idea創建spring boot項目很方便的,這裡我就不多說了。
二、頁面渲染在後端,用的是thymeleaf模版引擎
thymeleaf模版的引入,pox.xml中添加如下依賴
<!-- thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
頁面類型為.html文件,html文檔的<html>標籤內添加xmlns:th="http://www.thymeleaf.org"
,如下所示:
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
三、前端使用angularJs實現數據視圖的雙向綁定,並且用的angular自帶的resource模塊請求restful接口
因為頁面渲染在服務端,所以angular請求的模板視圖需要做相應的處理,後端controller內添加如下代碼:
@GetMapping(value = {"/fragments/add-data", "/fragments/search-data"}) public String indexIncludePage(HttpServletRequest request) { String path = request.getServletPath(); return path.substring(0, path.length() - 5); }
以上表示前端請求的這兩個/fragments/add-data,/fragments/search-data
視圖經服務端渲染後返回給前端調用者。
以下為angular的resource模塊的restful風格接口調用:
/** 自定義 Person 服務 */ .factory('Person', function ($resource) { var ctx = window.qbian._ctx; return $resource(ctx + '/person', {}, { submit: { method: 'POST' , url: ctx + '/person' , params : { name: '@name' , sex : '@sex' , interest : '@interest' } } , query: { method: 'GET' , url: ctx + '/person/search' , params : { pageNo: '@pageNo', pageSize: '@pageSize' , sex: '@sex' , name: '@name' , interest: '@interest' } } }); })
四、提供了提交數據的頁面和相關接口
angular的controller內添加如下代碼:
$scope.initPageSize = 9; // 初始化小於10,下一頁按鈕不可用 $scope.personV = { name : '', sex : '', interest : '', pageNo : 1 };
以上是查詢的初始化參數和分頁要用到的一個參數。頁面初始化時無數據,所以下一頁按鈕不可用。不添加任何查詢條件時默認參數全為空。
以下為html頁面內容:
<!--查詢參數--> <input ng-model="personV.name" type="text" class="form-control" placeholder="Name" /> <select ng-model="personV.sex" class="form-control" id="sex"> <option>男</option> <option>女</option> </select> <input ng-model="personV.interest" type="text" class="form-control" placeholder="Interest" /> <!--分頁代碼如下--> <ul class="pager"> <li><button ng-disabled="personV.pageNo < 2" ng-click="prevPage()" type="button" class="btn btn-sm btn-default">上一頁</button></li> <span>當前第(<span style="color: #00be67;font-weight: 600;" ng-bind="personV.pageNo"></span>)頁</span> <li><button ng-disabled="initPageSize < 10" ng-click="nextPage()" type="button" class="btn btn-sm btn-default">下一頁</button></li> </ul>
五、提供了多條件查詢的頁面和相關接口
四的內容就是多條件查詢相關。
六、提供了查詢結果匹配高亮顯示,分頁查詢等功能
查詢結果匹配高亮部分代碼如下:
/** * 檢索匹配關鍵字高亮 * @param queryBuilder 查詢引擎 * @param type 文檔類型 * @param highlightFieldList 高亮清單 * @param pageNo 頁碼 * @param pageSize 當頁顯示數據量 * @return 查詢結果 */ public JSONArray searchHighlight(QueryBuilder queryBuilder, String type, List<String> highlightFieldList , int pageNo, int pageSize) { StopWatch clock = new StopWatch(); clock.start(); // 設置高亮顯示 HighlightBuilder highlightBuilder = new HighlightBuilder().requireFieldMatch(true); if(highlightFieldList != null) { for(String field : highlightFieldList) { highlightBuilder.field(field, 10240); } } /** 以下兩行就是高亮相關代碼 */ highlightBuilder.preTags("<span style="color:red">"); highlightBuilder.postTags("</span>"); SearchResponse searchResponse = client.prepareSearch(INDEX_TYPE).setTypes(type) .setQuery(queryBuilder).highlighter(highlightBuilder) .addSort("date", SortOrder.DESC) .setFrom(pageNo * pageSize).setSize(pageSize) .setExplain(true).execute().actionGet(); SearchHit[] hits = searchResponse.getHits().getHits(); clock.stop(); LOG.info("searchHighlight: {} ms", clock.getTotalTimeMillis()); // 封裝查詢結果 JSONArray result = new JSONArray(); if(hits != null && hits.length > 0) { for(SearchHit hit : hits) { Map<String, HighlightField> highlightFields = hit.getHighlightFields(); JSONObject data = new JSONObject(); for(Entry<String, Object> entry : hit.getSource().entrySet()) { // 保存高亮字段 if(highlightFields != null && highlightFields.containsKey(entry.getKey())) { HighlightField titleField = highlightFields.get(entry.getKey()); Text[] fragments = titleField.fragments(); StringBuilder sb = new StringBuilder(); for(Text text : fragments) { sb.append(text); } data.put(entry.getKey(), sb.toString()); } else { data.put(entry.getKey(), entry.getValue()); } } result.add(data); } } return result; }
好了,說了這麼多還是演示以下吧
七、功能演示
因為採用的是elasticsearch集群,所以我就開啟了兩臺elasticsearch服務器,集群的詳細搭建在我上一篇文章內有詳細介紹。我現在啟動的兩臺es服務器的ip分別是:192.168.1.113對應節點名稱是node-1,192。168.1.129對應節點名稱是node-2,master節點是node-1,如下圖:
集群狀態
我們項目內的es相關配置在application-es.yml配置文件內,詳細配置如下:
#========================================= #================= elasticSearch config #========================================= es: ips: 192.168.1.113,192.168.1.129 port: 9300 cluster: test
然後啟動我們的項目:
啟動項目
以上表示啟動成功,然後我們再訪問首頁:localhost:8180/es
index頁面
我們可以在這裡提交一些數據,然後去搜索數據頁面查詢,這裡我已經提交了一些數據了,就直接去查詢了。
1、默認無條件查詢:
無條件查詢
查詢結果如下:
無條件查詢結果
可以看到我們的分頁的下一頁是可以點擊的,因為返回的數據量剛好是我們默認請求的數據量10條,所以我們認為它還是存在下一頁的。
下一頁按鈕點擊後:
無條件查詢第二頁數據
因為該頁返回的數據量小於我們請求的10條,所以我們認為這已經是最後一頁了,下一頁按鈕不可用。
2、有條件查詢
查詢愛“打籃球”的“男生”:
愛打籃球的男生查詢結果
查詢“男生”,愛好一個“球”:
“男生”,愛好“球”
以上就是elasticsearch的demo演示及其講解,源碼我放github了,下載下來就可以測試使用(前提是你也安裝了elasticsearch,不是集群的也可用)
源碼地址:https://github.com/Qbian61/elasticsearch-demo