1. 程式人生 > >JavaAPI實現Elasticsearch5.5.2一些常用的搜尋

JavaAPI實現Elasticsearch5.5.2一些常用的搜尋

前段時間學了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 disMaxQuery
disMaxQuery適用於多個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語句中的or
BoolQueryBuilder 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 < 1800
RangeQueryBuilder rangeQueryBuilder1 = QueryBuilders.rangeQuery("price").from(1200).to(1800);
sql:select * from sales where brand = ‘小米’ and price > 1200
BoolQueryBuilder 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其他的一些功能,比如搜尋結果高亮顯示、搜尋建議、聚合分析等等,持續更新中....如果我在上面的文章中,有哪些地方不對,請大家及時糾正,感激不盡!