JavaAPI實現Elasticsearch5.5.2一些常用的搜尋
前段時間學了elasticsearch的搜尋,但是一直都是用elasticsearch原生的命令完成一些搜尋,但是因為本人一直在搞java服務端開發,所以就根據elasticsearch官方的API和網上的一些資料對一些常用的搜尋通過java來實現了,下邊寫的一些比較常用也是很基礎的搜尋,我使用的elasticsearch版本是5.5.2。
一、首先構建elasticsearch客戶端
因為我是基於一個SpringBoot進行的完成的,這裡使用的是TransportClient,在專案給它定義了一個配置類,那麼我們需要他的時候,直接進行注入就可以了。
二、javaAPI搜尋語句簡單介紹@Configuration public class MyConfig { @Bean public TransportClient client() throws UnknownHostException{ //配置節點 InetSocketTransportAddress node = new InetSocketTransportAddress( InetAddress.getByName("localhost"), 9300 ); //配置settiong Settings settings = Settings.builder() .put("cluster.name", "my-application") .build(); TransportClient client = new PreBuiltTransportClient(settings); client.addTransportAddress(node); return client; }
使用java進行elasticsearch搜尋的時候,他的api算是很好使用的,基本上我們做的大多數的搜尋,整體java語句都是差不多的,首先我先把官方一個搜尋語句放到這裡,做一個簡單的註釋
其實,我們在進行搜尋查詢的時候,只需要關心QueryBuilders的構建和fiter的過濾就可以了。SearchResponse response = client.prepareSearch("index1", "index2") //index1,index2指的是我們需要查詢的索引,相當於資料庫的名稱 .setTypes("type1", "type2") //type1,type2是我們需要查詢的type,相當於資料庫的表名字 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //指的是我們需要採取的搜尋方式 .setQuery(QueryBuilders.termQuery("multi", "test")) // 主要是構建我們的查詢條件 .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18)) // 用於查詢的過濾 .setFrom(0).setSize(60) //這裡就是一個分頁功能 .setExplain(true) .get();
三、elasticsearch進行搜尋javaAPI的使用
3.1簡單搜尋
這個搜尋,我會把所有的java語句,寫出來,供大家進行參考,其他的搜尋我直接寫出QueryBuilers的構建
3.1.1.termQuery等值搜尋
我們在資料庫中進行查詢的時候,sql:select sales from tvs where brand = ‘小米’,那麼在elasticsearch中的javaapi怎麼寫呢?這裡我們用到一個termQuery,他相當於sql語句中的“=”,使用這個搜尋一般是對索引中keyword的mapping進行等值搜尋,例如
//確定搜尋的index和type
SearchRequestBuilder requestBuilder = client
.prepareSearch("tvs")
.setTypes("sales");
//構建query語句
TermQueryBuilder termQuery = QueryBuilders.termQuery("brand", "小米");
//我們可以將我們構建好的查詢打印出來
System.out.println(termQuery);
//進行搜尋
SearchResponse response = requestBuilder
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(termQuery)
.setFrom(0)
.setSize(10)
.execute()
.actionGet();
//檢視搜尋結果
for(SearchHit hit:response.getHits()){
Map<String, Object> source = hit.getSource();
System.out.println(source);
}
3.1.2 matchQuery 匹配查詢
matchQuery可以簡單理解為mysql中的like,但是我不知道我這麼理解對不對,因為在elasticsearch中使用matchQuery查詢時,他會對查詢的field進行分詞,打個比方,我們搜尋"聯想膝上型電腦",他可能會將他拆分為:“聯想”,“電腦”,“聯想電腦”,那麼如果一個filed中包括 聯想 兩個字就可以被搜出來。當然我們進行查詢的這個field的mapping必須是text型別。(如果是中文分詞的話,還需要配置中文分詞器),他的查詢語句和上邊基本相似
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", "聯想電腦");//title指定field
3.1.3matchAllQuery 查詢所用
查詢指定index和type中的所用記錄,相當於sql:select * from sales
MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
3.1.4 matchPhraseQuery短語搜尋MatchPhraseQueryBuilder matchPhraseQuery = QueryBuilders.matchPhraseQuery("title", "聯想電腦");
3.1.5 prefixQuery字首搜尋
如我我們需要查詢的title中有“大話西遊電影”,“大話西遊小說”,使用prefixQuery查詢“大話西遊”,那麼那兩條資料就會出來
PrefixQueryBuilder prefixQuery = QueryBuilders.prefixQuery("title", "大話西遊");
3.1.6 disMaxQuerydisMaxQuery適用於多個field的進行搜尋,我們在多個field搜尋時候,可能會遇到多個field匹配到了更多的詞會在前面,而一個field匹配了更多的詞就會排名靠後。disMax就是解決這個問題,dismax使搜尋到的結果,應該是某一個field中匹配到了儘可能多的關鍵詞,被排在前面;而不是儘可能多的field匹配到了少數的關鍵詞,排在了前面
DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery()
.add(QueryBuilders.matchQuery("title", "elastic"))
.add(QueryBuilders.matchQuery("content", "elastic search"));
對於一些簡單的搜尋,我先整理到這裡,其實還有好多。。。大家可以查詢javaAPI,這裡就不一一列出來。
3.2多條件搜尋
多條件搜尋也就是sql語句裡面的多個條件搜尋
3.2.1boolQuery 組合查詢條件
boolQuery用來將搜尋的條件進行組合,即將多個組合條件組合在一起,常用的幾種組合方式有must、should、mustNot,我們拿下面對應的sql語句舉例子(同上面一樣,我們只需要將構建好的QueryBuilder放到裡面就可以了,參考3.1.1)
sql:select * from sales where brand = '小米' and color='紅色',通過bool將兩個查詢條件組合,must相當於sql中的= 必須匹配的意思
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("brand", "小米"))
.must(QueryBuilders.termQuery("color", "紅色"));
sql:select * from sales where brand = '小米' or color='紅色';使用should相當於sql語句中的orBoolQueryBuilder boolQuery2 = QueryBuilders.boolQuery();
boolQuery2.should(QueryBuilders.termQuery("brand", "小米"))
.should(QueryBuilders.termQuery("color", "紅色"));
//sql:select * from sales where brand = '小米' and color != '紅色' mustNot相當於!= 必須不匹配BoolQueryBuilder boolQuery3 = QueryBuilders.boolQuery();
boolQuery2.must(QueryBuilders.termQuery("brand", "小米"))
.mustNot(QueryBuilders.termQuery("color", "紅色"));
sql:select
* from sales where (brand = '小米' or color = '紅色') and brand != '長虹'BoolQueryBuilder boolQuery4 = QueryBuilders.boolQuery();
BoolQueryBuilder boolQuery5 = QueryBuilders.boolQuery();
boolQuery5.should(QueryBuilders.termQuery("brand", "小米"))
.should(QueryBuilders.termQuery("color", "紅色"));
boolQuery4.must(boolQuery5)
.mustNot(QueryBuilders.termQuery("brand", "長虹"));
3.2.2Filter 過濾filter用來對搜尋條件進行過濾,我們在sql語句中的>,<等等都可以用它來實現,我們同樣用例子來說明
sql:select * from sales where price > 1200 and price < 1800
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gt("1200");
sql:select * from sales where price > 1200 and price < 1800RangeQueryBuilder rangeQueryBuilder1 = QueryBuilders.rangeQuery("price").from(1200).to(1800);
sql:select * from sales where brand = ‘小米’ and price > 1200BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("brand", "小米"));
boolQuery.must(QueryBuilders.rangeQuery("price").gt("1200"));
3.2.3Sort
排序
使用addSort對指定的field進行排序,我們可以選擇是DESC還是ASE,如果不寫預設是倒敘
SearchResponse response = client.prepareSearch("tvs")
.setTypes("sales")
.setQuery(QueryBuilders.matchAllQuery())
.addSort("price", SortOrder.DESC)
.setFrom(0)
.setSize(10)
.execute()
.actionGet();
3.2.4分頁
分頁的語句很簡單,我在上邊的語句中都已經提到了
.setFrom(1).setSize(10) //表示第1頁開始,一頁有10條記錄
這篇文章主要是對elasticsearch的一些搜尋,通過javaAPI來實現了,我會在下面的文章中,整理出elasticsearch其他的一些功能,比如搜尋結果高亮顯示、搜尋建議、聚合分析等等,持續更新中....如果我在上面的文章中,有哪些地方不對,請大家及時糾正,感激不盡!