ElasticSearch是一個基於Lucene的搜索服務器。它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並做爲Apache許可條款下的開放源碼發佈,是當前流行的企業級搜索引擎。設計用於雲計算中,可以達到實時搜索,穩定,可靠,快速,安裝使用方便。java
咱們創建一個網站或應用程序,並要添加搜索功能,可是想要完成搜索工做的建立是很是困難的。咱們但願搜索解決方案要運行速度快,咱們但願能有一個零配置和一個徹底免費的搜索模式,咱們但願可以簡單地使用JSON經過HTTP來索引數據,咱們但願咱們的搜索服務器始終可用,咱們但願可以從一臺開始並擴展到數百臺,咱們要實時搜索,咱們要簡單的多租戶,咱們但願創建一個雲的解決方案。所以咱們利用Elasticsearch來解決全部這些問題以及可能出現的更多其它問題。node
咱們須要將這中搜索模式集中到咱們的項目中去,從而實現大量數據的搜索功能,性能遠遠超越數據庫查詢!
web
ElasticSearch : You Know, for Search!spring
這裏安裝不在過多的贅述,這裏推薦官方的中文文檔,安裝指引 安裝完成以後,運行啓動,打開瀏覽器,訪問http://localhost:9200 將看到一下信息(cluster_name很是重要後面的代碼要用到):數據庫
{ "name" : "2g-ucq2", "cluster_name" : "elasticsearch", "cluster_uuid" : "tpMpsSenRpaBPugKlG7QaA", "version" : { "number" : "5.5.0", "build_hash" : "260387d", "build_date" : "2017-06-30T23:16:05.735Z", "build_snapshot" : false, "lucene_version" : "6.6.0" }, "tagline" : "You Know, for Search" }
咱們使用Maven,所以須要修改POM文件內容,添加以下依賴便可。apache
<!--ElasticSearch支持文件--> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.5.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.7</version> </dependency>
在classpath源目錄下建立log4j2.properties文件,內容信息以下json
appender.console.type =Console appender.console.name =Console appender.console.layout.type =PatternLayout appender.console.layout.pattern = [%t] %-5p %c - %m%n rootLogger.lever = info rootLogger.appenderRef.console.ref = Console
咱們將核心的client對象,使用配置註解進行配置,方便往後取用瀏覽器
package com.tao.spring.config; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.net.InetAddress; import java.net.UnknownHostException; /** * 本文件由周濤建立,位於com.tao.spring.config包下 * 建立時間2018/1/26 20:42 * 郵箱:zhoutao@xiaodouwangluo.com * 做用:建立ES的client對象,方便後期使用 */ @Configuration public class ElasticSearchConfig { @Bean public TransportClient client() throws UnknownHostException{ //注意這裏的端口是TCP端口9300,而非HTTP接口9200 InetSocketTransportAddress node = new InetSocketTransportAddress(InetAddress.getByName("localhost"),9300); //機器名稱,能夠首頁查詢,這個不能出現錯誤,不然沒法鏈接ES Settings settings=Settings.builder().put("cluster.name","elasticsearch").build(); TransportClient client = new PreBuiltTransportClient( settings); client.addTransportAddress(node); return client; } }
下面將依次實現數據的增刪改查,以及符合查詢,這裏咱們的的類型是book,其具備兩個屬性分別是bookid和bookprice,具體說明參考註釋。
首先須要注入對象服務器
@Autowired TransportClient client;
需求:實現根據bookid獲取數據的信息
/** * 使用ES進行簡單的搜索操做 * @param bookid * @return */ @RequestMapping(value = "/get",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public String getInfoById(@RequestParam(name = "bookid") String bookid){ if (Strings.isNullOrEmpty(bookid)){ return "缺乏參數,或參數格式不正確"; } //tao指定的書索引,book指的是類型,後面相同,不在作敘述 GetResponse getFields = client.prepareGet("tao", "book", bookid).get(); //這裏須要作些判斷,沒有沒有判斷,在沒有查到的狀況,會拋出異常信息 if ( getFields ==null || !getFields.isExists()){ return "沒有查詢到結果信息"; }else{ return getFields.getSource().toString(); } }
需求:提供bookid和bookprice來插入數據到ES
/** * 插入一條數據到ES中 * @param bookid * @param bookprice * @return **/ @RequestMapping(value = "/add",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public String addInfoToES(String bookid,float bookprice){ if (Strings.isNullOrEmpty(bookid) || bookprice <= 0){ return "參數不存在或者參數格式異常!"; } try { //構造JSON數據,方便使用 XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject() .field("bookid", bookid) .field("bookprice", bookprice) .endObject(); IndexResponse indexResponse = client.prepareIndex("tao","book").setSource(xContentBuilder).get(); return "新增圖書信息完成,圖書信息ID爲:"+indexResponse.getId(); }catch (IOException ex){ ex.printStackTrace(); return "新增圖書信息失敗,失敗信息:"+ex.getMessage(); } }
需求:根據給定的id,來刪除數據信息
/** * 從ES中刪除一條數據 * @param bookid * @return */ @RequestMapping(value = "/del",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public String delInfo(String bookid){ if (Strings.isNullOrEmpty(bookid)){ return "參數不存在或者參數異常"; } DeleteResponse deleteResponse = client.prepareDelete("tao", "book", bookid).get(); //將會返回兩個結果:NOT_FOUND 未發現 DELETED 已刪除 return deleteResponse.getResult().toString() ; }
修改指定id的數據信息
/** * 根據Id簡單的修改信息 * @param bookid * @param bookprice * @return */ @RequestMapping(value = "/modify",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public String nodify(String bookid,@RequestParam(required = false) Float bookprice){ UpdateRequest request = new UpdateRequest("tao","book",bookid); try { XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject(); if (bookprice.floatValue() <= 0){ return "參數異常或者參數格式錯誤!"; }else { xContentBuilder.field("bookprice",bookprice).endObject(); } request.doc(xContentBuilder); UpdateResponse updateResponse = client.update(request).get(); return updateResponse.getResult().toString(); }catch (Exception e) { e.printStackTrace(); return "更新數據出現異常,異常信息:"+e.getMessage(); } }
需求:精準查詢bookid,範圍查詢bookprice,gt_bookprice 最小的價格,lt_bookprice 最大價格
/** * 使用ES進行復雜查詢 * @param bookid * @param gt_bookprice * @param lt_bookprice * @return */ @RequestMapping(value = "/getConditon",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public String querty(@RequestParam(required = false) String bookid,@RequestParam(defaultValue = "0.0") Float gt_bookprice,@RequestParam(required = false)Float lt_bookprice){ //構造查詢條件 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); if (!Strings.isNullOrEmpty(bookid)){ boolQueryBuilder.must(QueryBuilders.matchQuery( "bookid",bookid)); } //構造範圍查詢 RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("bookprice").from(gt_bookprice,true); if(lt_bookprice!=null && lt_bookprice.floatValue() > 0){ rangeQuery.to(lt_bookprice); } //整合爲一個查詢條件 boolQueryBuilder.filter(rangeQuery); SearchRequestBuilder searchRequestBuilder = client.prepareSearch("tao") .setTypes("book") .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) .setQuery(boolQueryBuilder) .setFrom(0) .setSize(10); //能夠直接輸出,方便查看請求體 System.out.println("查詢條件:"+searchRequestBuilder); SearchResponse searchResponse = searchRequestBuilder.get(); List<Map> result = new ArrayList<>(); //從查詢接口中遍歷數據進行封裝操做 for (SearchHit hitFields:searchResponse.getHits()){ result.add(hitFields.getSource()); } return result.toString(); }