前段時間學了elasticsearch的搜索,但是一直都是用elasticsearch原生的命令完成一些搜索,但是因爲本人一直在搞java服務端開發,所以就根據elasticsearch官方的API和網上的一些資料對一些常用的搜索通過java來實現了,下邊寫的一些比較常用也是很基礎的搜索,我使用的elasticsearch版本是5.5.2。
一、首先構建elasticsearch客戶端
因爲我是基於一個SpringBoot進行的完成的,這裏使用的是TransportClient,在項目給它定義了一個配置類,那麼我們需要他的時候,直接進行注入就可以了。
@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;
}
二、javaAPI搜索語句簡單介紹
使用java進行elasticsearch搜索的時候,他的api算是很好使用的,基本上我們做的大多數的搜索,整體java語句都是差不多的,首先我先把官方一個搜索語句放到這裏,做一個簡單的註釋
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();
其實,我們在進行搜索查詢的時候,只需要關心QueryBuilders的構建和fiter的過濾就可以了。
三、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其他的一些功能,比如搜索結果高亮顯示、搜索建議、聚合分析等等,持續更新中....如果我在上面的文章中,有哪些地方不對,請大家及時糾正,感激不盡!