在安裝Elasticsearch以前咱們須要先安裝jdk的環境,這些都是老生常談,咱們不去多加敘述,具體的安裝步驟咱們能夠參考http://www.javashuo.com/article/p-eyxnyjvz-cz.html ,這裏有詳細的Elasticsearch及jdk安裝步驟。安裝好以後咱們能夠找到安裝目錄bin下的批處理文件來啓動項目.php
看到這樣的界面後咱們能夠在瀏覽器裏輸入http://localhost:9200/能夠看到返回了一段json,其中對外服務的http端口,默認爲9200,9300是客戶端的端口。在這裏elasticsearch咱們就安裝完了。html
{ "name": "node-1", "cluster_name": "my-application", "cluster_uuid": "YWYqGhDnSE-z3pbVDEs8rQ", "version": { "number": "6.3.0", "build_flavor": "default", "build_type": "zip", "build_hash": "424e937", "build_date": "2018-06-11T23:38:03.357887Z", "build_snapshot": false, "lucene_version": "7.3.1", "minimum_wire_compatibility_version": "5.6.0", "minimum_index_compatibility_version": "5.0.0" }, "tagline": "You Know, for Search" }
elasticsearch安裝完後咱們須要安裝head插件管理咱們的elasticsearch,上面連接教程中elasticsearch使用的是2.4.4的版本,而我用的是6.3.0的版本,在cmd中使用es命令的方式已經不可用了。咱們須要本身區去官網下載安裝包,在這以前還須要先安裝node.js和grunt,參考https://www.cnblogs.com/Onlywjy/p/Elasticsearch.html咱們能很快的完成elasticsearch及head的安裝和配置。安裝完成後咱們能夠經過cmd進入到head的安裝目錄經過「npm run start 」來啓動head插件,在瀏覽器中輸入」http://localhost:9100「來訪問。java
pom依賴:node
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
application.ymlmysql
spring: data: elasticsearch: cluster-name: my-application #elasticsearch/config文件下elasticsearch.yml中設置的cluster.name
cluster-nodes: 127.0.0.1:9300 #客戶端端口,啓動elasticsearch時默認爲9300
參考http://www.javashuo.com/article/p-cmqcwytf-hw.html,偷懶的同窗,能夠直接看下面,咱們完成了pojo,dao,controller的編寫,因爲只是作了個demo就沒有使用service層去規範。在clone連接中代碼時候咱們會遇到一些錯誤,下面咱們着手解決這些錯誤。web
pojospring
import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; /** * @Author: gaofeng_peng * @Date: 2018/6/24 10:44 */ @Document(indexName = "product", type = "book") public class Book { @Id String id; String name; String message; String type; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getType() { return type; } public void setType(String type) { this.type = type; }
在上述代碼中@Document註解中 indexName指的是索引,能夠理解成mysql中數據庫 ,type既對應的是數據表。sql
dao數據庫
public interface BookDao extends ElasticsearchRepository<Book, String> { Book findBooksById(String id); void deleteById(String id); }
參考的文檔中,dao層沒有寫接口,在後面的實現中會報錯,忖度做者的用意controller下getBookById中 bookDao.findOne() 方法 對應了 findBooksById,insertBook中bookDao.delete() 對應deleteById,相信這麼簡單你們都能看出來。npm
controller
package com.bookstore.controller.backend; import com.bookstore.dao.BookDao; import com.bookstore.pojo.Book; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @Author: gaofeng_peng * @Date: 2018/6/24 11:02 */ @RestController @RequestMapping("book") public class BookController { @Autowired private BookDao bookDao; /** * 一、查 id * * @param id * @return */ @GetMapping("/get/{id}") public Book getBookById(@PathVariable String id) { return bookDao.findBooksById(id); } /** * 二、查 ++:全文檢索(根據整個實體的全部屬性,可能結果爲0個) * * @param q * @return */ @GetMapping("/select/{q}") public List<Book> testSearch(@PathVariable String q) { QueryStringQueryBuilder builder = new QueryStringQueryBuilder(q); Iterable<Book> searchResult = bookDao.search(builder); Iterator<Book> iterator = searchResult.iterator(); List<Book> list = new ArrayList<Book>(); while (iterator.hasNext()) { list.add(iterator.next()); } return list; } /** * 三、查 +++:分頁、分數、分域(結果一個也很多) * * @param page * @param size * @param q * @return */ @GetMapping("/{page}/{size}/{q}") public List<Book> searchCity(@PathVariable Integer page, @PathVariable Integer size, @PathVariable String q) { // 分頁參數 Pageable pageable = new PageRequest(page, size); FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = { new FunctionScoreQueryBuilder.FilterFunctionBuilder( QueryBuilders.matchQuery("name", q), ScoreFunctionBuilders.weightFactorFunction(1000)), new FunctionScoreQueryBuilder.FilterFunctionBuilder( QueryBuilders.matchQuery("message", q), ScoreFunctionBuilders.weightFactorFunction(1000)) }; FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(functions); // 分數、分頁 SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable) .withQuery(functionScoreQueryBuilder).build(); Page<Book> searchPageResults = bookDao.search(searchQuery); return searchPageResults.getContent(); } /** * 四、增 * * @param book * @return */ @PostMapping("/insert") public Book insertBook(Book book) { bookDao.save(book); return book; } /** * 五、刪 id * * @param id * @return */ @DeleteMapping("/delete/{id}") public Book insertBook(@PathVariable String id) { Book book = bookDao.findBooksById(id); bookDao.deleteById(id); return book; } /** * 六、改 * * @param book * @return */ @PutMapping("/update") public Book updateBook(Book book) { bookDao.save(book); return book; } }
在這裏咱們要着重講一下參考文檔中的searchCity 方法,下面是做者的寫法:
/** * 三、查 +++:分頁、分數、分域(結果一個也很多) * @param page * @param size * @param q * @return * @return */ @GetMapping("/{page}/{size}/{q}") public List<Book> searchCity(@PathVariable Integer page, @PathVariable Integer size, @PathVariable String q) { // 分頁參數 Pageable pageable = new PageRequest(page, size); // 分數,並自動按分排序 FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery() .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", q)), ScoreFunctionBuilders.weightFactorFunction(1000)) // 權重:name 1000分 .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("message", q)), ScoreFunctionBuilders.weightFactorFunction(100)); // 權重:message 100分 // 分數、分頁 SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable) .withQuery(functionScoreQueryBuilder).build(); Page<Book> searchPageResults = bookDao.search(searchQuery); return searchPageResults.getContent(); }
你們注意下紅色的部分,因爲咱們在配置依賴時候沒有指定elasticsearch的版本,如今若是仍是直接clone上面的依賴的話會發現已經沒有add的方法了,一種方式去指定版本,都走到這一步了,咱們採起另外一種方式使用
FunctionScoreQueryBuilder functionScoreQuery(ScoreFunctionBuilder function)方法,具體看下面
public List<Book> searchCity(@PathVariable Integer page, @PathVariable Integer size, @PathVariable String q) { // 分頁參數 Pageable pageable = new PageRequest(page, size); FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = { new FunctionScoreQueryBuilder.FilterFunctionBuilder( QueryBuilders.matchQuery("name", q), ScoreFunctionBuilders.weightFactorFunction(1000)), new FunctionScoreQueryBuilder.FilterFunctionBuilder( QueryBuilders.matchQuery("message", q), ScoreFunctionBuilders.weightFactorFunction(1000)) }; FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(functions); // 分數、分頁 SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable) .withQuery(functionScoreQueryBuilder).build(); Page<Book> searchPageResults = bookDao.search(searchQuery); return searchPageResults.getContent(); }
上面咱們使用的是:SpringData
封裝,直接在 dao 接口繼承 ElasticsearchRepository的方式,做者很全面還提供了elasticsearchTemplate的方式,
package com.bookstore.controller.backend; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @Author: gaofeng_peng * @Date: 2018/6/24 10:58 */ @RestController @RequestMapping("/template") public class BookControllerTemplate { @Autowired ElasticsearchTemplate elasticsearchTemplate; /** * 查詢全部 * @throws Exception */ @GetMapping("/all") public List<Map<String, Object>> searchAll() throws Exception { //這一步是最關鍵的 Client client = elasticsearchTemplate.getClient(); // @Document(indexName = "product", type = "book") SearchRequestBuilder srb = client.prepareSearch("product").setTypes("book"); SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery()).execute().actionGet(); // 查詢全部 SearchHits hits = sr.getHits(); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); for (SearchHit hit : hits) { Map<String, Object> source = hit.getSource(); list.add(source); System.out.println(hit.getSourceAsString()); } return list; } }
到此位置簡單的增刪改查就完成了,還需一點注意的是做者@RestController什麼的沒加,記得加上。。。。。
上面的是FunctionScoreQueryBuilder的Java代碼示例,總有那麼一種方式適合你。
在這裏咱們安裝了google 的restlet client 插件來方便測試,固然,也可使用head插件上的複合查詢來測試。
圖片比較大這裏咱們只放部分的測試結果,就不一一列舉了,至此整個項目就完成了,有什麼不足,歡迎你們指點。