Elasticsearch 檢索

說到查詢,那麼索引也是一個繞不開的話題,能夠說,沒有索引就沒有檢索,先來看一個示意圖 工具

 

左邊是索引過程,右邊是檢索過程。關鍵的步驟是分詞過程,我用等號表示這兩個過程同樣,並且,必須同樣,這個等號並非模糊的流程的相同,並且必須是邏輯也相同。 簡單來說,採用的分詞器和分詞流程須要同樣,不然,頗有可能填進去的文檔,搜不出來。網站

 

本篇重點在如何用JAVA API實現查詢上,就不深刻說索引的過程了,之後有時間再深刻。ui

 

對於查詢,有兩個基礎的類型,Match查詢,和Term查詢。這也是跟索引過程相關的。剛開始接觸的索引,我就想,若是把全部的內容都作搜索,那麼一是須要創建很是多的索引,再一個是要保存特別多的原始數據,隨着瞭解的加深,我發現並非這樣的。spa

 

在進行索引的時候,先新建文檔,在往文檔中添加字段時,有Index設置和Store設置。index設置就是是否要對這個字段用分詞器進行分詞。舉個例子,有個字段A,內容爲中華人民共和國國歌,以中文分詞器IK爲例,若是不進行分詞,那麼往索引中插入的時候,直接用一個詞「中華人民共和國國歌」。若是A字段設置爲進行索引,那麼IK分詞器就會將「中華人民共和國國歌」分解爲「中華人民共和國」和「國歌」兩個詞,往索引中添加的時候,是兩個記錄。翻譯

對於Store選項,若是選擇Yes,就是存儲這個字段的原始值,對於字段A來講,就是保存「中華人民共和國國歌」,這樣,在檢索以後,若是查詢到字段A,能夠返回A的原始值。若是選擇Store爲No,而且設置爲A進行索引,那麼A字段的原始值就不可知了。索引中只存在「中華人民共和國」和「國歌」,並不存在「中華人民共和國國歌」。你能夠檢索到字段A,可是A的原始值是什麼,ES就不知道了,須要去原始的數據源中找出來。blog

 

這兩個設置是十分關鍵的,好比id,基本不須要進行索引分詞,直接存儲就是了,並且,你查詢的時候,也確定不須要對id進行分詞,因此,這個就是term查詢的用處。term就是詞的意思,Lucene中將分詞以後的結果成爲Term,因此,像id這樣的不須要分詞的,直接就跟通過分詞步驟的詞同樣了,能夠用這個詞直接去倒排索引中查詢了。因此,Term查看的字段,最好設置爲Index爲No,不然,通常搜不到。排序

 

Store選項能夠有效減少ES的存儲規模,你想一想,你用百度去搜索,確定都會到目標的網頁,而不是在百度裏面瀏覽,百度只要告訴你,你想去的網頁的URL就能夠了。因此,在進行索引的時候,像整個網頁的內容,並非須要的,須要的是對整個網頁進行分詞以後產生的詞,而後就能夠將原始的網頁文本丟棄了。固然,百度也存儲了這個內容的,百度快照就是。索引

 

Match查詢就是須要對搜索的關鍵詞進行分詞,而後將分詞的結果拿到倒排索引裏面去檢索,檢索以後,再對這個結果進行相關性分詞,而後排序進行輸出。能夠看出,Match查詢要比Term查詢多了至少兩步,分詞和相關性計算。文檔

 

好比說咱們要索引一個網頁,網頁有一些基本meta信息。那麼首先,咱們把網頁給抓取到,分析網頁裏面的內容。網頁的meta信息比較關鍵,咱們提取出來,準備構建一個文檔,網頁的關鍵字,meta信息,更新時間等這些均可以成爲io

 

除了這兩類最主要的,還有範圍查詢,bool查詢等,這些都是跟SQL同樣的組合查詢。

SearchRequestBuilder是最主要的查詢方法,QueryBuilders提供了多種構造查詢語句的方式。Kibana裏面集成的DevTools是使用Query DSL很是方便的一個工具。

 

SearchRequestBuilder searchRequestBuilder = client.prepareSearch((String[])tempIndices.toArray(new String[tempIndices.size()]));

searchRequestBuilder.setTypes(typesName);

searchRequestBuilder.setQuery(qb);

searchRequestBuilder.addStoredField(field);//設置返回的字段,注意,這裏返回的必須是Stored是Yes的。

searchRequestBuilder.setSize(size);

searchRequestBuilder.setFrom(from);

SearchResponse searchResponse = requestBuilder.execute().actionGet();

 

那麼如何構造Query?這就是如何從咱們的查詢轉化成ES的Query DSL,有關kibana使用的就是DSL,有關DSL的介紹,查看elastic.co或者網站翻譯的Elasticsearch權威指南。儘可能仍是參考elastic.co的,由於ES更新比較快,最靠譜的仍是上面的介紹。

 

QueryBuilders.rangeQuery();//範圍查詢

 

QueryBuilders.geoDistanceRangeQuery("fieldName", new GeoPoint(Long.parseLong("經度"), Long.parseLong("緯度")))

.from( "1km")

.to("2km")

.includeLower(true)

.includeUpper(true);//地理位置插敘

 

QueryBuilders.termQuery("field", "keyword");//term查看

 

QueryBuilders.matchQuery("field", "keyword");//match查看

 

另外,可使用QueryBuilders.boolQuery();將上面的query聯合起來,鏈接的關係有Must(等同於SQL的AND),MustNot(等同於SQL的NOT),SHOULD(等同於OR)

 

基本上,以上都是初步的查詢API。

相關文章
相關標籤/搜索