1. 程式人生 > >solr簡介、學習詳細過程!(超詳細~)

solr簡介、學習詳細過程!(超詳細~)

solr是什麼呢?

一、Solr它是一種開放原始碼的、基於 Lucene Java 的搜尋伺服器,易於加入到 Web 應用程式中。

二、Solr 提供了層面搜尋(就是統計)、命中醒目顯示並且支援多種輸出格式(包括XML/XSLT 和JSON等格式)。它易於安裝和配置,而且附帶了一個基於 HTTP 的

管理介面。Solr已經在眾多大型的網站中使用,較為成熟和穩定。

三、Solr 包裝並擴充套件了 Lucene,所以Solr的基本上沿用了Lucene的相關術語。更重要的是,Solr 建立的索引與 Lucene 搜尋引擎庫完全相容。

四、通過對Solr 進行適當的配置,某些情況下可能需要進行編碼,Solr 可以閱讀和使用構建到其他 Lucene 應用程式中的索引。

五、此外,很多 Lucene 工具(如Nutch、 Luke)也可以使用Solr 建立的索引。可以使用 Solr 的表現優異的基本搜尋功能,也可以對它進行擴充套件從而滿足企業的需要。

solr的優點

通過上面Solr的簡介,可知solr的優點包括以下幾個方面:

            ①高階的全文搜尋功能;

            ②專為高通量的網路流量進行的優化;

            ③基於開放介面(XML和HTTP)的標準;

            ④綜合的HTML管理介面;

            ⑤可伸縮性-能夠有效地複製到另外一個Solr搜尋伺服器;

            ⑥使用XML配置達到靈活性和適配性;

            ⑦可擴充套件的外掛體系。

solr VS Lucene!?

在比較solr和Lucene之前,要知道什麼是Lucene,那麼首先就來回顧Lucene是個什麼東東?

     Lucene是一個基於Java的全文資訊檢索工具包,它不是一個完整的搜尋應用程式,而是為你的應用程式提供索引和搜尋功能。Lucene 目前是 Apache Jakarta(雅加達) 家族中的一個開源專案。也是目前最為流行的基於Java開源全文檢索工具包。目前已經有很多應用程式的搜尋功能是基於 Lucene ,比如Eclipse 幫助系統的搜    索功能。Lucene能夠為文字型別的資料建立索引,所以你只要把你要索引的資料格式轉化的文字格式,Lucene 就能對你的文件進行索引和搜尋。

那麼,solr和它相比,是”輸“了?還是“贏”了呢?

      其實,Solr與Lucene 並不是競爭對立關係,恰恰相反Solr 依存於Lucene,因為Solr底層的核心技術是使用Lucene 來實現的,Solr和Lucene的本質區別有以下三點:搜尋伺服器,企業級和管理。Lucene本質上是搜尋庫,不是獨立的應用程式,而Solr是。Lucene專注於搜尋底層的建設,而Solr專注於企業應用。Lucene不負責支撐搜尋服務所必須的管理,而Solr負責。所以說,一句話概括 Solr: Solr是Lucene面向企業搜尋應用的擴充套件。

下面是solr和 lucene的架構圖: 
這裡寫圖片描述

這個圖很繁瑣,看不懂,大家不要灰心,在後面的程式碼裡你就能夠了解了這個圖所講的。

不難看出,綠色的就是lucene的模組,而藍色的就是solr擴充套件了lucene。從圖上可以看出以下幾點:

a. 一個真正的擁有動態欄位(Dynamic Field)和唯一鍵(Unique Key)的資料模式(Data Schema) 
b. 對Lucene查詢語言的強大擴充套件! 
c. 支援對結果進行動態的分組和過濾 
d. 高階的,可配置的文字分析 
e. 高度可配置和可擴充套件的快取機制 
f. 效能優化 
g. 支援通過XML進行外部配置 
h. 擁有一個管理介面 
i. 可監控的日誌 
j. 支援高速增量式更新(Fast incremental Updates)和快照發布(Snapshot Distribution)

說到這,solr的簡介就到此結束了,相信大家也對solr有了初步的瞭解,下面開始介紹一下solr的常用屬性有哪些?

solr的使用屬性及配置檔案

Document 包括一個或多個 Field。Field 包括名稱、內容以及告訴 Solr 如何處理內容的元資料。

例如,Field可以包含字串、數字、布林值或者日期,也可以包含你想新增的任何型別,只需用在solr的配置檔案中進行相應的配置即可。Field可以使用大量的選項來描述,這些

選項告訴 Solr 在索引和搜尋期間如何處理內容。

現在,檢視以下圖片 中列出的重要屬性的子集:

這裡寫圖片描述

在這就先提一下solr的重要檔案之一,就是schema.xml的配置檔案。

(一) schema.xml

schema.xml這個配置檔案可以在你下載solr包的安裝解壓目錄的\solr\example\solr\collection1\conf中找到,它就是solr模式關聯的檔案。

開啟這個配置檔案,你會發現有詳細的註釋。模式組織主要分為三個重要配置:

一、Fieldtype

Fieldtype:就是屬性型別的意思,像int,String,Boolean種類型,而在此配置檔案中,FieldType就有這種定義屬性的功能,看下面的圖片: 
這裡寫圖片描述

圖片上有我們熟悉的int,String,boolean,那麼,後面的配置,是什麼呢?那麼我們就來介紹一下後面的引數:

這裡寫圖片描述

二、Field

Field:是新增到索引檔案中出現的屬性名稱,而宣告型別就需要用到上面的type,如圖所示:

這裡寫圖片描述

ps:①field: 固定的欄位設定;②dynamicField: 動態的欄位設定,用於後期自定義欄位,*號萬用字元.例如: test_i就是int型別的動態欄位。

還有一個特殊的欄位copyField,一般用於檢索時用的欄位這樣就只對這一個欄位進行索引分詞就行了copyField的dest欄位如果有多個source一定要設定multiValued=true,否則會報錯的。 
這裡寫圖片描述

在Field裡也有一些屬性需要了解,看圖: 
這裡寫圖片描述 
這裡寫圖片描述

三、其他配置

①uniqueKey: 唯一鍵,這裡配置的是上面出現的fileds,一般是id、url等不重複的。在更新、刪除的時候可以用到。

②defaultSearchField:預設搜尋屬性,如q=solr就是預設的搜尋那個欄位

③solrQueryParser:查詢轉換模式,是並且還是或者(AND/OR必須大寫)

(二)solrconfig.xml

       solrconfig.xml這個配置檔案可以在你下載solr包的安裝解壓目錄的E:\Work\solr-4.2.0-src-idea\solr\example\solr\collection1\conf中找到,這個配置檔案內容有點多,主要內容有:使

       用的lib配置,包含依賴的jar和Solr的一些外掛;元件資訊配置;索引配置和查詢配置,下面詳細說一下索引配置和查詢配置.

一、索引indexConfig

       Solr 效能因素,來了解與各種更改相關的效能權衡。 下表概括了可控制 Solr 索引處理的各種因素:

這裡寫圖片描述 
這裡寫圖片描述

二、查詢配置query

這裡寫圖片描述 
這裡寫圖片描述 
(三)加入中文分詞器

       中文分詞在solr裡面是沒有預設開啟的,需要我們自己配置一箇中文分詞器。目前可用的分詞器有smartcn,IK,Jeasy,庖丁。其實主要是兩種,一種是基於中科院ICTCLAS的

       隱式馬爾科夫HMM演算法的中文分詞器,如smartcn,ictclas4j,優點是分詞準確度高,缺點是不能使用使用者自定義詞庫;另一種是基於最大匹配的分詞器,如IK ,Jeasy,庖丁,

       優點是可以自定義詞庫,增加新詞,缺點是分出來的垃圾詞較多。各有優缺點看應用場合自己衡量選擇吧。

       下面給出兩種分詞器的安裝方法,任選其一即可,推薦第一種,因為smartcn就在solr發行包的contrib/analysis-extras/lucene-libs/下,就是lucene-analyzers-smartcn-4.2.0.jar,首選

        在solrconfig.xml中加一句引用analysis-extras的配置,這樣我們自己加入的分詞器才會引到的solr中.

        <lib dir="../../../contrib/analysis-extras/lib" regex=".*\.jar" />

一、 smartcn 分詞器的安裝

       首選將發行包的contrib/analysis-extras/lucene-libs/ lucene-analyzers-smartcn-4.2.0.jar複製到\solr\contrib\analysis-extras\lib下,在solr本地應用資料夾下,開啟/solr/conf/scheme.xml,

       編輯text欄位型別如下,新增以下程式碼到scheme.xml中的相應位置,就是找到fieldType定義的那一段,在下面多新增這一段就好了:

複製程式碼

01.<fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="0">  
02.  
03.      <analyzer type="index">  
04.  
05.        <tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>  
06.  
07.        <filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>  
08.  
09.      </analyzer>  
10.  
11.      <analyzer type="query">  
12.  
13.         <tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>  
14.  
15.        <filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>  
16.  
17.      </analyzer>  
18.  
19.</fieldType>  

複製程式碼

 

如果需要檢索某個欄位,還需要在scheme.xml下面的field中,新增指定的欄位,用text_ smartcn作為type的名字,來完成中文分詞。如 text要實現中文檢索的話,就要做如下的配置:

       <field name ="text" type ="text_smartcn" indexed ="true" stored ="false" multiValued ="true"/>

       還有一個就是 IK分詞器,因為在5.0之後才有的IKAnalyzer的jar包,這裡學習用的是solr4.9版本,在這裡就不多詳細介紹IKAnalyzer。有興趣的同學可以根據下面的路徑下載Jar包:

       路徑:http://ik-analyzer.googlecode.com/files/IK%20Analyzer%202012FF_hf1.zip.

下載後解壓出來檔案中的三個複製到\solr\contrib\analysis-extras\lib目錄中.

IKAnalyzer2012FF_u1.jar      分詞器jar包

IKAnalyzer.cfg.xml           分詞器配置檔案

 Stopword.dic                分詞器停詞字典,可自定義新增內容

複製後就可以像smartcn一樣的進行配置scheme.xml了.

複製程式碼

01.<fieldType name="text_ik" class="solr.TextField">  
02.  
03. <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>  
04.  
05. </fieldType>  
06.  
07. <field name ="text" type ="text_ik" indexed ="true" stored ="false" multiValued ="true"/> 

複製程式碼

 

現在來驗證下是否新增成功,首先使用StartSolrJetty來啟動solr服務,啟動過程中如果配置出錯,一般有兩個原因:一是配置的分詞器jar找不到,也就是你沒有複製jar包到\solr\contrib\analysis-extras\lib目前下;二是分詞器版本不對導致的分詞器介面API不一樣出的錯,要是這個錯的話就在檢查分詞器的相關文件,看一下支援的版本是否一樣.

如果在啟動過程中沒有報錯的話說明配置成功了.我們可以進入到http://localhost:8983/solr地址進行測試一下剛加入的中文分詞器.在首頁的Core Selector中選擇你配置的Croe

後點擊下面的Analysis,在Analyse Fieldname / FieldType裡選擇你剛才設定的欄位名稱或是分詞器型別,在Field Value(index)中輸入:中國人,點選右面的分詞就行了。

solr的POJO

一、什麼是POJO? 
POJO(Plain Ordinary Java Object)簡單的Java物件,實際就是普通JavaBeans,是為了避免和EJB混淆所創造的簡稱。

使用POJO名稱是為了避免和EJB混淆起來, 而且簡稱比較直接. 其中有一些屬性及其getter setter方法的類,沒有業務邏輯,有時可以作為VO(value -object)或dto(Data Transform

Object)來使用.當然,如果你有一個簡單的運算屬性也是可以的,但不允許有業務方法,也不能攜帶有connection之類的方法。

二、POJO的特點

POJO特點如下:

①POJO是Plain OrdinaryJava Object的縮寫不錯,但是它通指沒有使用Entity Beans的普通java物件,可以把POJO作為支援業務邏輯的協助類。

②POJO實質上可以理解為簡單的實體類,顧名思義POJO類的作用是方便程式設計師使用資料庫中的資料表,對於廣大的程式設計師,可以很方便的將POJO類當做物件來進行使用,

當然也是可以方便的呼叫其get,set方法。POJO類也給我們在struts框架中的配置帶來了很大的方便。

三、POJO的程式碼演示

POJO有一些private的引數作為物件的屬性。然後針對每個引數定義了get和set方法作為訪問的介面。例如:

複製程式碼

 1 public class User {
 2 
 3        private long id;
 4 
 5        private String name;
 6 
 7 public void setId(long id) {
 8 
 9          this. id = id;
10 
11 }
12 
13 public void setName(String name) {
14 
15         this. name=name;
16 
17 }
18 
19 public long getId() {
20 
21          return id;
22 
23 }
24 
25 public String getName() {
26 
27        return name;
28 
29 }
30 
31 }

複製程式碼

 

 

POJO物件有時也被稱為Data物件,大量應用於表現現實中的物件。如果專案中使用了Hibernate框架,有一個關聯的xml檔案,使物件與資料庫中的表對應,物件的屬性與表中的欄位相對應。

四、POJO與JavaBean的區別

POJO和JavaBean是我們常見的兩個關鍵字,一般容易混淆,POJO全稱是Plain Ordinary Java Object / Pure Old Java Object,中文可以翻譯成:普通Java類,具有一部分

getter/setter方法的那種類就可以稱作POJO,但是JavaBean則比POJO複雜很多,Java Bean是可複用的元件,對 Java Bean並沒有嚴格的規範,理論上講,任何一個 Java 類都可以是一個 Bean 。但通常情況下,由於 Java Bean 是被容器所建立(如 Tomcat) 的,所以 Java Bean 應具有一個無參的構造器,另外,通常 Java Bean還要實現 Serializable 介面用於實現 Bean 的永續性。 Java Bean 是不能被跨程序訪問的。JavaBean是一種元件技術,就好像你做了一個扳子,而這個扳子會在很多地方被拿去用,這個扳子也提供多種功能(你可以拿這個扳子扳、錘、撬等等),而這個扳子就是一個元件。一般在web應用程式中建立一個數據庫的對映物件時,我們只能稱它為POJO。POJO(Plain Old Java Object)這個名字用來強調它是一個普通java物件,而不是一個特殊的物件,其主要用來指代那些沒有遵從特定的Java物件模型、約定或框架(如EJB)的Java物件。理想地講,一個POJO是一個不受任何限制的Java物件(除了Java語言規範)[1] 。

錯誤的認識

POJO是這樣的一種“純粹的”JavaBean,在它裡面除了JavaBean規範的方法和屬性沒有別的東西,即private屬性以及對這個屬性方法的public的get和set方法。我們會發現這樣的JavaBean很“單純”,它只能裝載資料,作為資料儲存的載體,而不具有業務邏輯處理的能力。

真正的意思

POJO = “Plain Old Java Object”,是MartinFowler等發明的一個術語,用來表示普通的Java物件,不是JavaBean, EntityBean 或者 SessionBean。POJO不擔當任何特殊的角色,也不實現任何特殊的Java框架的介面如,EJB,JDBC等等。即POJO是一個簡單的普通的Java物件,它不包含業務邏輯或持久邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不繼承或不實現任何其它Java框架的類或介面。

下面是摘自Martin Fowler個人網站的一句話:

“We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it’s

caught on very nicely.”--Martin Fowler

我們疑惑為什麼人們不喜歡在他們的系統中使用普通的物件,我們得到的結論是——普通的物件缺少一個響亮的名字,因此我們給它們起了一個,並且取得了很好的效果。——Martin Fowler

solr軟體安裝與簡介

溫馨提示:

一、保證環境必須在JDK1.7上;

二、tomCat建議在tomcat7以上版本;

三、如若不是solr4.9版本的,solr5.0以上建議tomCat在tomcat8以上;

四、solr4.9版本的核心類及常用的屬性,和solr5.0以上的差不多,但是還有細微的區別,請注意!

一、安裝solr步驟

步驟一、配置solr與TomCat整合

先把solr的壓縮包去官網(http://archive.apache.org/dist/lucene/solr/)下載並解壓,名稱為: 
這裡寫圖片描述 
這裡寫圖片描述

點選解壓之後的資料夾,如圖所示: 
這裡寫圖片描述

看到如上圖所示,就證明下載和解壓成功。接下來就是與tomcat整合(在此次學習中,我用的是tomcat8.0.33);

以下就是整合具體的步驟: 
1、將解壓之後 的資料夾裡example資料夾下的solr資料夾中的所有檔案(不含solr資料夾本身) 
這裡寫圖片描述

2、拷貝到D:\solrDemo\Solr檔案下(solrDemo資料夾和Solr需自己手動建立),如下圖所示: 
這裡寫圖片描述

3、將解壓後的solr-4.9.0下的dist目錄下的solr-4.9.0.war 檔案 
這裡寫圖片描述

4、拷貝到D:\apache-tomcat-7.0.54\webapps資料夾下,重新命名為solr.war,一定要自己解壓這個war檔案,(啟動tomcat會自動解壓,但是這個檔案裡面的lib目錄的東西好像是解壓不出來),看到webapps下面多了一個solr資料夾,如下圖: 
這裡寫圖片描述

5、開啟D:\solrDemo\Solr\collection1\conf下的solrconfig.xml檔案: 
這裡寫圖片描述

6、把以下這幾個配置註釋掉,因為用不到。 
這裡寫圖片描述

7、繼續往下找到DataDir節點,修改值為${solr.data.dir:d:/solrDemo/Solr/data} ,data資料夾為儲存查詢索引和資料的地方,data資料夾自己建立。 
這裡寫圖片描述

8、開啟E:\學習資料\tomcat\apache-tomcat-8.0.33\webapps\solr\WEB-INF資料夾下的web.xml檔案,增加env-entry節點(預設是註釋掉的),修改值為value>D:/solrDemo/Solr,注意斜線。 
這裡寫圖片描述

9、將解壓後的solr-4.9.0資料夾下的dist/solrj-lib下的所有jar包 
這裡寫圖片描述

10、拷貝到E:\學習資料\tomcat\apache-tomcat-8.0.33\lib資料夾下 
這裡寫圖片描述

11、啟動Tomcat之後,在位址列輸入:http://localhost:8080/solr,會出現以下報錯的地方,如圖所示: 
這裡寫圖片描述

這個錯誤就是缺jar包(缺slf4j.jar)。把E:\學習資料\課外知識學習\solr1\solr-4.9.0\example\lib\ext這個路徑下的所有jar包, 
這裡寫圖片描述

拷進E:\學習資料\tomcat\apache-tomcat-8.0.33\webapps\solr\WEB-INF\lib這個資料夾,也就是應用的lib資料夾下。同時把solr包下的E:\學習資料\課外知識學習\solr1\solr-4.9.0\example\resources\log4j.properties這個日誌檔案 
這裡寫圖片描述

拷進E:\學習資料\tomcat\apache-tomcat-8.0.33\webapps\solr\WEB-INF\classes(沒有classes資料夾自己手工建立一下)就可以了。

然後再重啟tomcat。

tomcat重啟中……………….

在訪問http://localhost:8080/solr,出現下圖,書名配置solr環境成功: 
這裡寫圖片描述

二、介紹solr軟體

在這出現了一個軟體就是Solr的軟體,下面就和大家一起來看看這個軟體怎麼用 
這裡寫圖片描述

上圖為安裝solr環境的軟體的左面截圖,首先來看看這幅圖的講解:

1、Dashboard:就是上面全圖就是這個按鈕的功能;

2、Logging:檢視日誌;

3、Core Admin:新增core使用者,這個可重要也可不重要,預設是collection1,這個就是新增一個和collection1具有一樣功能的使用者,用來檢索和查詢。點選之

後會出現下面的截圖: 
這裡寫圖片描述 
提示一下:

name:給core隨便起個名字; 
instanceDir:core的安裝目錄,這裡就是之前在tomcat/solrhome/目錄下建立的core1資料夾; 
dataDir:指定用於存放lucene索引和log日誌檔案的目錄路徑,該路徑是相對於core根目錄(在單core模式下,就直接是相對於solr_home了),預設值是當前core目錄下的data; 
config:用於指定solrconfig.xml配置檔案的檔名,啟動時會去core1/config目錄下去查詢; 
schema:即用來配置你的schema.xml配置檔案的檔名的,schema.xml配置檔案應該存放在當前core目錄下的conf目錄下。但是下載的solr裡沒有這個檔案,所以我也不管了; 
屬性都填上,然後點選Add Core,就建立完成了。

再看最下面的下拉框:點選之後會出現collection1,點選collection1出現如下截圖: 
這裡寫圖片描述

因為我在這之前添加了一個索引文件,所以我的顯示的Num Docs和Max Doc 是有值的,沒有安裝就是為0;

就來介紹一下選中core角色後生成的一些按鈕功能。

1、Overview:是瀏覽你的索引文件。其中包括最後開啟時間、文件記憶體數量、文件最大數量等等一些資訊; 
2、Analysis:解析瀏覽。如下圖:

這裡寫圖片描述

看左上方的Field Value(Index):這個是定義你要索引的屬性值; 
右上方的Field Value(Query):這個是根據輸入的值,來進行查詢; 
底下的Analyse Fieldname / FieldType :就是你要往哪個屬性裡新增索引的值。

3、dataImport:就是資料的引進。 
4、FIles、Ping、Pligins/Stats 這些不怎麼常用,這裡就不多詳細介紹了。 
5、Query:是根據索引屬性查詢,效果如下: 
這裡寫圖片描述

看到這,相信有的同學就要問了,拿這些是幹嘛的呢?下面就介紹一下他們是幹嘛的: 
q:查詢字串,必須寫,格式為:“索引屬性:屬性值”,必須遵守這種格式,否則查不出來。

fq:filter query。使用Filter Query可以充分利用Filter Query Cache,提高檢索效能。作用:在q查詢符合結果中同時是fq查詢符合的,例如:

    q=mm&fq=date_time:[20081001 TO 20091031],找關鍵字mm,並且date_time是20081001到20091031之間的。

fl:field list。指定返回結果欄位。以空格“ ”或逗號“,”分隔。

start:用於分頁定義結果起始記錄數,預設為0。

rows:用於分頁定義結果每頁返回記錄數,預設為10。

sort:排序,格式:sort=field name+desc|asc 。示例:(inStock desc, price asc)表示先 “inStock” 降序, 再 “price” 升序,預設是相關性降序。

df:預設的查詢欄位,一般預設指定。

q.op:覆蓋schema.xml的defaultOperator(有空格時用”AND”還是用”OR”操作邏輯),一般預設指定。必須大寫

wt:writer type。指定查詢輸出結構格式,預設為“xml”。在solrconfig.xml中定義了查詢輸出格式:xml、json、python、ruby、php、phps、custom。

qt:query type,指定查詢使用的Query Handler,預設為“standard”。

explainOther:設定當debugQuery=true時,顯示其他的查詢說明。

defType:設定查詢解析器名稱。

timeAllowed:設定查詢超時時間。

omitHeader:設定是否忽略查詢結果返回頭資訊,預設為“false”。

indent:返回的結果是否縮排,預設關閉,用 indent=true|on 開啟,一般除錯json,php,phps,ruby輸出才有必要用這個引數。

version:查詢語法的版本,建議不使用它,由伺服器指定預設值。

debugQuery:設定返回結果是否顯示Debug資訊。

以上這些就是solr的一些引數,下面就來介紹一下,查詢的語法有哪些?

語法:

1.匹配所有文件::

2.強制、阻止和可選查詢:

1) Mandatory:查詢結果中必須包括的(for example, only entry name containing the word make)

Solr/Lucene Statement:+make, +make +up ,+make +up +kiss

2) prohibited:(for example, all documents except those with word believe)

Solr/Lucene Statement:+make +up -kiss

3) optional:

Solr/Lucene Statement:+make +up kiss

3.布林操作:AND、OR和NOT布林操作(必須大寫)與Mandatory、optional和prohibited相似。

1) make AND up = +make +up :AND左右兩邊的操作都是mandatory

2) make || up = make OR up=make up :OR左右兩邊的操作都是optional

3) +make +up NOT kiss = +make +up –kiss

4) make AND up OR french AND Kiss不可以達到期望的結果,因為AND兩邊的操作都是mandatory的。

  1. 子表示式查詢(子查詢):可以使用“()”構造子查詢。

示例:(make AND up) OR (french AND Kiss)

5.子表示式查詢中阻止查詢的限制:

示例:make (-up):只能取得make的查詢結果;要使用make (-up :)查詢make或者不包括up的結果。

6.多欄位fields查詢:通過欄位名加上分號的方式(fieldName:query)來進行查詢

示例:entryNm:make AND entryId:3cdc86e8e0fb4da8ab17caed42f6760c

7.萬用字元查詢(wildCard Query):

1) 萬用字元?和:“”表示匹配任意字元;“?”表示匹配出現的位置。

示例:ma?(ma後面的一個位置匹配),ma??(ma後面兩個位置都匹配)

2) 查詢字元必須要小寫:+Ma +be**可以搜尋到結果;+Ma +Be**沒有搜尋結果.

3) 查詢速度較慢,尤其是萬用字元在首位:主要原因一是需要迭代查詢欄位中的每個term,判斷是否匹配;二是匹配上的term被加到內部的查詢,當terms數量達到1024的時候,查詢會失敗。

4) Solr中預設萬用字元不能出現在首位(可以修改QueryParser,設定

setAllowLeadingWildcard為true)

5) set setAllowLeadingWildcard to true.

8.模糊查詢、相似查詢:不是精確的查詢,通過對查詢的欄位進行重新插入、刪除和轉換來取得得分較高的查詢解決(由Levenstein Distance Algorithm演算法支援)。

1) 一般模糊查詢:示例:make-believ~

2) 門檻模糊查詢:對模糊查詢可以設定查詢門檻,門檻是0~1之間的數值,門檻越高表面相似度越高。示例:make-believ~0.5、make-believ~0.8、make-believ~0.9

9.範圍查詢(Range Query):Lucene支援對數字、日期甚至文字的範圍查詢。結束的範圍可以使用“*”萬用字元。

示例:

1) 日期範圍(ISO-8601 時間GMT):sa_type:2 AND a_begin_date:[1990-01-01T00:00:00.000Z TO 1999-12-31T24:59:99.999Z]

2) 數字:salary:[2000 TO *]

3) 文字:entryNm:[a TO a]

10.日期匹配:YEAR, MONTH, DAY, DATE (synonymous with DAY) HOUR, MINUTE, SECOND, MILLISECOND, and MILLI (synonymous with MILLISECOND)可以被標誌成日期。

示例:

1) r_event_date:[* TO NOW-2YEAR]:2年前的現在這個時間

2) r_event_date:[* TO NOW/DAY-2YEAR]:2年前前一天的這個時間

在solr裡,也有函式,接下來就看看solr是怎樣通過函式查詢的:

函式查詢 可以利用 numeric欄位的值 或者 與欄位相關的的某個特定的值的函式,來對文件進行評分。

  1. 使用函式查詢的方法

這裡主要有三種方法可以使用函式查詢,這三種s方法都是通過solr http介面的。

1) 使用FunctionQParserPlugin。ie: q={!func}log(foo)

2) 使用“val”內嵌方法

內嵌在正常的solr查詢表示式中。即,將函式查詢寫在 q這個引數中,這時候,我們使用“val”將函式與其他的查詢加以區別。

ie:entryNm:make && val:ord(entryNm)

3) 使用dismax中的bf引數

使用明確為函式查詢的引數,比如說dismax中的bf(boost function)這個引數。 注意:bf這個引數是可以接受多個函式查詢的,它們之間用空格隔開,它們還可以帶上權重。所以,當我們使用bf這個引數的時候,我們必須保證單個函式中是沒有空格出現的,不然程式有可能會以為是兩個函式。

示例:

q=dismax&bf=”ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3

  1. 函式的格式(Function Query Syntax)

目前,function query 並不支援 a+b 這樣的形式,我們得把它寫成一個方法形式,這就是 sum(a,b).

  1. 使用函式查詢注意事項

1) 用於函式查詢的field必須是被索引的;

2) 欄位不可以是多值的(multi-value)

  1. 可以利用的函式 (available function)

1) constant:支援有小數點的常量; 例如:1.5 ;SolrQuerySyntax:val:1.5

2) fieldvalue:這個函式將會返回numeric field的值,這個欄位必須是indexd的,非multiValued的。格式很簡單,就是該欄位的名字。如果這個欄位中沒有這樣的值,那麼將會返回0。

3) ord:對於一個欄位,它所有的值都將會按照字典順序排列,這個函式返回你要查詢的那個特定的值在這個順序中的排名。這個欄位,必須是非multiValued的,當沒有值存在的時候,將返回0。例如:某個特定的欄位只能去三個值,“apple”、“banana”、“pear”,那麼ord(“apple”)=1,ord(“banana”)=2,ord(“pear”)=3.需要注意的是,ord()這個函式,依賴於值在索引中的位置,所以當有文件被刪除、或者新增的時候,ord()的值就會發生變化。當你使用MultiSearcher的時候,這個值也就是不定的了。

4) rord:這個函式將會返回與ord相對應的倒排序的排名。

格式: rord(myIndexedField)。

5) sum:這個函式的意思就顯而易見啦,它就是表示“和”啦。

格式:sum(x,1) 、sum(x,y)、 sum(sqrt(x),log(y),z,0.5)

6) product:product(x,y,…)將會返回多個函式的乘積。格式:product(x,2)、product(x,y)

7) div:div(x,y)表示x除以y的值,格式:div(1,x)、div(sum(x,100),max(y,1))

8) pow:pow表示冪值。pow(x,y) =x^y。例如:pow(x,0.5) 表示開方pow(x,log(y))

9) abs:abs(x)將返回表示式的絕對值。格式:abs(-5)、 abs(x)

10) log:log(x)將會返回基數為10,x的對數。格式: log(x)、 log(sum(x,100))

11) Sqrt:sqrt(x) 返回 一個數的平方根。格式:sqrt(2)、sqrt(sum(x,100))

12) Map:如果 x>=min,且x<=max,那麼map(x,min,max,target)=target.如果 x不在[min,max]這個區間內,那麼map(x,min,max,target)=x.

格式:map(x,0,0,1)

13) Scale:scale(x,minTarget,maxTarget) 這個函式將會把x的值限制在[minTarget,maxTarget]範圍內。

14) query :query(subquery,default)將會返回給定subquery的分數,如果subquery與文件不匹配,那麼將會返回預設值。任何的查詢型別都是受支援的。可以通過引用的方式,也可以直接指定查詢串。

例子:q=product(popularity, query({!dismax v=’solr rocks’}) 將會返回popularity和通過dismax 查詢得到的分數的乘積。

q=product(popularity, query($qq)&qq={!dismax}solr rocks 跟上一個例子的效果是一樣的。不過這裡使用的是引用的方式

q=product(popularity, query($qq,0.1)&qq={!dismax}solr rocks 在前一個例子的基礎上又加了一個預設值。

15) linear: inear(x,m,c)表示 m*x+c ,其中m和c都是常量,x是一個變數也可以是一個函式。例如: linear(x,2,4)=2*x+4.

16) Recip:recip(x,m,a,b)=a/(m*x+b)其中,m、a、b是常量,x是變數或者一個函式。當a=b,並且x>=0的時候,這個函式的最大值是1,值的大小隨著x的增大而減小。例如:recip(rord(creationDate),1,1000,1000)

17) Max: max(x,c)將會返回一個函式和一個常量之間的最大值。

例如:max(myfield,0)

solr用POJO新增和刪除文件並用軟體查詢

pom.xml

複製程式碼

 1         <!-- https://mvnrepository.com/artifact/org.apache.solr/solr-solrj -->
 2         <dependency>
 3             <groupId>org.apache.solr</groupId>
 4             <artifactId>solr-solrj</artifactId>
 5             <version>4.4.0</version>
 6         </dependency>
 7         <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
 8         <dependency>
 9             <groupId>commons-logging</groupId>
10             <artifactId>commons-logging</artifactId>
11             <version>1.2</version>
12         </dependency>

複製程式碼

 

 

程式碼需要用到一個POJO,即簡單的javaBean,程式碼如下:

複製程式碼

 1 package solrPOJOPackage;
 2 
 3 import java.util.List;
 4 
 5 import org.apache.solr.client.solrj.beans.Field;
 6 
 7 public class NewsBean {
 8 
 9       @Field
10       private String id;
11 
12       @Field
13       private String name;
14 
15       @Field
16       private String author;
17 
18       @Field
19       private String description;
20 
21       @Field("links")
22       private List<String> relatedLinks;
23 
24       public NewsBean(){
25 
26       }
27 
28       public String getId() {
29         return id;
30       }
31 
32       public void setId(String id) {
33         this.id = id;
34       }
35 
36 
37       public String getName() {
38         return name;
39       }
40 
41       public void setName(String name) {
42         this.name = name;
43       }
44 
45       public String getAuthor() {
46         return author;
47       }
48 
49       public void setAuthor(String author) {
50         this.author = author;
51       }
52 
53       public String getDescription() {
54         return description;
55       }
56 
57       public void setDescription(String description) {
58         this.description = description;
59       }
60 
61       public List<String> getRelatedLinks() {
62         return relatedLinks;
63       }
64 
65       public void setRelatedLinks(List<String> relatedLinks) {
66         this.relatedLinks = relatedLinks;
67       }
68 
69 }

複製程式碼

 

 

以下是程式碼的實現:

首先是用POJO來新增索引文件:

複製程式碼

  1 package solrPOJOPackage;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Arrays;
  5 import java.util.Collection;
  6 import java.util.List;
  7 import java.util.Random;
  8 
  9 import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
 10 import org.apache.solr.client.solrj.impl.HttpSolrServer;
 11 
 12 //採用POJOs增加、刪除索引 
 13 public class solrTest {
 14 
 15     //定義全域性solr軟體路徑
 16     public static final String SOLR_URL = "http://localhost:8080/solr";
 17 
 18     public static void main(String[] args) {
 19 
 20         // 通過瀏覽器檢視結果?
 21         // 要保證bean中各屬性的名稱在conf/schema.xml中存在,如果查詢,要儲存被索引
 22         // http://172.168.63.233:8983/solr/collection1/select?q=description%3A%E6%94%B9%E9%9D%A9&wt=json&indent=true
 23 
 24         //刪除索引文件
 25         //delBeans();
 26 
 27         //新增索引文件
 28        AddBeans();
 29       }
 30 
 31     //看文件random.docs
 32      public static Random rand = new Random(47);
 33 
 34      //定義String陣列,用來定義authors
 35       public static String[] authors = { "張三", "李四", "王五", "趙六", "張飛", "劉備","關雲" };
 36 
 37      //定義links屬性的陣列
 38       public static String[] links = {
 39 
 40           "http://repository.sonatype.org/content/sites/forge-sites/m2e/",
 41 
 42           "http://news.ifeng.com/a/20140818/41626965_0.shtml",
 43 
 44           "http://news.ifeng.com/a/20140819/41631363_0.shtml?wratingModule_1_9_1",
 45 
 46           "http://news.ifeng.com/topic/19382/",
 47 
 48           "http://news.ifeng.com/topic/19644/" 
 49     };
 50 
 51 
 52       public static String genAuthors() {
 53 
 54        //JDK中,List介面有一個例項方法List<E> subList(int fromIndex, int toIndex),其作用是返回一個以fromIndex為起始索引(包含),以toIndex為終止索引(不包    //含)的子列表(List)。 
 55        //subList: 取List中下標為0到6的元素。
 56        //rand.nextInt(7): 給定一個引數n,nextInt(n)將返回一個大於等於0小於n的隨機數,即:0 <= nextInt(n) < n。
 57         List<String> list = Arrays.asList(authors).subList(0, rand.nextInt(7));
 58 
 59         //定義空的字串,接收從list集合中取出的author屬性
 60         String str = "";
 61         for (String tmp : list) {
 62 
 63           str += " " + tmp;
 64 
 65         }
 66 
 67         return str;
 68 
 69       }
 70 
 71      //擷取從list集合中取出下標為0-4的links屬性值
 72       public static List<String> genLinks() {
 73 
 74         return Arrays.asList(links).subList(0, rand.nextInt(5));
 75 
 76       }
 77 
 78     //新增索引資訊
 79       public static void AddBeans() {
 80             String[] words = { "中央全面深化改革領導小組", "第四次會", "審議了國企薪酬制度改", "考試招生制度改革",
 81                 "傳統媒體與新媒體融合", "相關邵內容檔案", "習大大強調要", "逐步規範國有企業收入分配秩序",
 82                 "實現薪酬水平適當", "結構合理、管理規範監督有效", "對不合理的偏", "過高收入進行調整",
 83                 "深化考試招生制度改革", "總的目標是形成分類", "綜合評價", "多元錄取的試招生模", "健全促進公平",
 84                 "科學選才", "監督有力的體制機", "多樣", "手段先進", "具有競爭力的新型主流媒體",
 85                 "建成幾家擁有強大實力和傳播力", "公信", "影響力的新型媒體集團" };
 86 
 87             long start = System.currentTimeMillis();
 88             Collection<NewsBean> docs = new ArrayList<NewsBean>();
 89             //1、DocumentObjectBinder binder = new DocumentObjectBinder();
 90             for (int i = 1; i < 300; i++) {
 91               NewsBean news = new NewsBean();
 92               news.setId("id" + i);
 93               news.setName("news" + i);
 94               news.setAuthor(genAuthors());
 95               news.setDescription(words[i % 21]);
 96               news.setRelatedLinks(genLinks());
 97            // 2、 SolrInputDocument doc1 = binder.toSolrInputDocument(news);
 98               docs.add(news);
 99             }
100             try {
101 
102              //通過路徑得到伺服器
103               HttpSolrServer server = new HttpSolrServer(SOLR_URL);
104 
105               //向伺服器請求寫入
106               server.setRequestWriter(new BinaryRequestWriter());
107 
108 
109               // 第一種方式寫入:增加後經過執行commit函式commit (981ms)
110               // 3、server.addBeans(docs);
111               //4、server.commit();
112 
113          // 第二種方式寫入:增加doc後立即commit (946ms)
114             // UpdateRequest req = new UpdateRequest();
115            //req.setAction(ACTION.COMMIT, false, false);
116           // req.add(docs);
117           //UpdateResponse rsp = req.process(server);
118 
119              // 第三種方式寫入:增加docs,其中server.add(docs.iterator())效率更快。
120               // the most optimal way of updating all your docs
121               // in one http request(481ms)
122              //迭代把索引文件加到伺服器上去。
123               server.addBeans(docs.iterator());
124 
125                //優化索引;
126               server.optimize(); 
127             } catch (Exception e) {
128               System.out.println(e);
129             }
130             System.out.println("新增索引資訊成功,共花費了"
131                 + (System.currentTimeMillis() - start)+"毫秒");
132 
133            //新增成功效果見圖一
134          //solr軟體新增成功之後查詢效果見圖二
135           }
136 
137     //再加上刪除文件的程式碼吧
138       public static void delBeans() {
139         //開始計時(m/s)
140             long start = System.currentTimeMillis();
141 
142             try {
143 
144               //得到伺服器的入口
145               HttpSolrServer server = new HttpSolrServer(SOLR_URL);
146 
147               //定義id的集合
148               List<String> ids = new ArrayList<String>();
149 
150               //迴圈得到id
151               for (int i = 1; i < 300; i++) {
152                 ids.add("id" + i);
153               }
154 
155               //刪除
156               server.deleteById(ids);
157 
158               // 提交
159               server.commit();
160 
161             } catch (Exception e) {
162               System.out.println(e);
163             }
164             System.out.println("刪除索引資訊成功,共花費了"
165                 + (System.currentTimeMillis() - start)+"毫秒");
166 
167           //刪除成功效果見圖三
168          //solr軟體刪除之後查詢效果見圖四
169           }
170 }

複製程式碼

 

以上程式碼中,看到有三種顏色的字型。這三種不同顏色字型的程式碼都是向伺服器寫入索引物件,字型為紅色的程式碼第1句是例項化DocumentObjectBinder物件,第2句就是把NewsBean的POJO轉成SolrInputDocument物件,這麼做的目的是:減少了Document文件和JavaBean相互轉換時的麻煩,1、2、3、4句是一起出現而組成了第一種寫入方法;而紫色字型的相比較紅色字型來說呢,處理的效率要快一點,但是還是不太理想,而綠色字型的程式碼效率快,值得選擇。

注:

  雖然作者是這樣說的,但是我自己測試之後,情況並不是完全如其所說,仁者見仁智者見智,大家可以自己多測試測試,根據自己的情況選擇。如下是我測試的結果:

  第三種方法:
新增索引資訊成功,共花費了3837毫秒
刪除索引資訊成功,共花費了3824毫秒

新增索引資訊成功,共花費了2023毫秒
刪除索引資訊成功,共花費了1337毫秒

新增索引資訊成功,共花費了2759毫秒
刪除索引資訊成功,共花費了1274毫秒

新增索引資訊成功,共花費了2049毫秒
刪除索引資訊成功,共花費了1330毫秒

第二種方法:
新增索引資訊成功,共花費了3243毫秒
刪除索引資訊成功,共花費了1380毫秒

新增索引資訊成功,共花費了2005毫秒
刪除索引資訊成功,共花費了1393毫秒

新增索引資訊成功,共花費了2621毫秒
刪除索引資訊成功,共花費了1398毫秒

第一種辦法:
新增索引資訊成功,共花費了2134毫秒
刪除索引資訊成功,共花費了1869毫秒

新增索引資訊成功,共花費了2024毫秒
刪除索引資訊成功,共花費了1311毫秒

新增索引資訊成功,共花費了2264毫秒
刪除索引資訊成功,共花費了1445毫秒

 

綠色字型程式碼裡有一個是optimize,這個是優化索引的功能,看看原始碼: (參考:http://my.oschina.net/qige/blog/173008
優化索引 : 
public UpdateResponse optimize(boolean waitFlush, boolean waitSearcher, int maxSegments ) throws SolrServerException, IOException { 
return new UpdateRequest().setAction( UpdateRequest.ACTION.OPTIMIZE, waitFlush, waitSearcher, maxSegments ).process( this );//同樣呼叫process,通過setAction引數,在CommonHttpSolrServer類方法request()中主要執行的是合併和壓縮 setAction都是為了對物件ModifiableSolrParams(這個物件在最終CommonHttpSolrServer的request方法中用的到)進行賦值 
}

紫色字型裡的setAction: 
public UpdateResponse commit( boolean waitFlush, boolean waitSearcher ) throws Solr ServerException, IOException {

    //看到了嗎?setAction都是為了對物件ModifiableSolrParams(這個物件在最終CommonHttpSolrServerrequest的request方法中用的到)
   在提交索引的時候也是呼叫的process方法
    return new UpdateRequest().setAction( UpdateRequest.ACTION.COMMIT, waitFlush, waitSearcher ).process( this );

}

圖一:這裡寫圖片描述

圖二: 
這裡寫圖片描述

圖三:這裡寫圖片描述

圖四: 
這裡寫圖片描述

最後總結一下步驟,步驟如下:

1、建立POJO; 
2、建立Java專案; 
3、建立一個含有main方法的類,包含addBeas和DelBeans兩個自調方法; 
4、執行mian方法; 
5、執行成功,列印臺出現標記; 
6、去solr軟體檢視。

採用SolrInputDocument物件新增和刪除索引並用軟體查詢

複製程式碼

 1 package solrSolrInputDocumentPackage;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Collection;
 5 import java.util.List;
 6 
 7 import org.apache.solr.client.solrj.impl.HttpSolrServer;
 8 import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION;
 9 import org.apache.solr.client.solrj.request.UpdateRequest;
10 import org.apache.solr.client.solrj.response.UpdateResponse;
11 import org.apache.solr.common.SolrInputDocument;
12 
13 //採用 SolrInputDocument物件 增加、刪除索引 
14 public class solrSolrInput {
15 
16      public static final String SOLR_URL = "http://localhost:8080/solr";
17 
18      public static void main(String[] args) {
19 
20             //通過瀏覽器檢視結果
21             //http://172.168.63.233:8983/solr/collection1/select?q=name%3A%E6%94%B9%E9%9D%A9&wt=json&indent=true
22             AddDocs();
23             //delDocs();
24           }
25 
26      public static void AddDocs() {
27 
28             String[] words = { "中央全面深化改革領導小組", "第四次會議", "審議了國企薪酬制度改革", "考試招生制度改革",
29                 "傳統媒體與新媒體融合等", "相關內容檔案", "習強調要", "逐步規範國有企業收入分配秩序",
30                 "實現薪酬水平適當", "結構合理、管理規範、監督有效", "對不合理的偏高", "過高收入進行調整",
31                 "深化考試招生制度改革", "總的目標是形成分類考試", "綜合評價", "多元錄取的考試招生模式", "健全促進公平",
32                 "科學選才", "監督有力的體制機制", "著力打造一批形態多樣", "手段先進", "具有競爭力的新型主流媒體",
33                 "建成幾家擁有強大實力和傳播力", "公信力", "影響力的新型媒體集團" };
34 
35             long start = System.currentTimeMillis();
36 
37             Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
38 
39             for (int i = 1; i < 300; i++) {
40               SolrInputDocument doc1 = new SolrInputDocument();
41               doc1.addField("id", "id" + i, 1.0f);
42               doc1.addField("name", words[i % 21], 1.0f);
43               doc1.addField("price", 10 * i);
44               docs.add(doc1);
45             }
46 
47             try {
48 
49               HttpSolrServer server = new HttpSolrServer(SOLR_URL);
50 
51               // 可以通過三種方式增加docs,其中server.add(docs.iterator())效率最高
52               //1、 增加後通過執行commit函式commit (936ms)
53                       server.add(docs);
54                       server.commit();
55 
56               // 2、增加doc後立即commit (946ms)
57               UpdateRequest req = new UpdateRequest();
58               req.setAction(ACTION.COMMIT, false, false);
59               req.add(docs);
60               UpdateResponse rsp = req.process(server);
61 
62               // 3、the most optimal way of updating all your docs 
63               // in one http request(432ms)
64               server.add(docs.iterator());
65             } catch (Exception e) {
66               System.out.println(e);
67             }
68             System.out.println("time elapsed(ms):"
69                 + (System.currentTimeMillis() - start));
70           }
71 
72      public static void delDocs() {
73             long start = System.currentTimeMillis();
74             try {
75               HttpSolrServer server = new HttpSolrServer(SOLR_URL);
76               List<String> ids = new ArrayList<String>();
77               for (int i = 1; i < 300; i++) {
78                 ids.add("id" + i);
79               }
80               server.deleteById(ids);
81               server.commit();
82             } catch (Exception e) {
83               System.out.println(e);
84             }
85             System.out.println("time elapsed(ms):"
86                 + (System.currentTimeMillis() - start));
87           }
88 
89 
90 }

複製程式碼

 

 

看完以上程式碼,感覺和POJO的新增,刪除索引沒什麼差別,但是,總有不同之處,

在POJO裡有一個索引優化,不知大家還記不記得, server.optimize(); 就是這個,就是因為這個方法,才會使得效率大大提高,這也就是細微之處的差別。

這個方法雖然和POJO的新增、刪除的功能是一樣的,但是大多數會選用POJO這種方法來進行索引管理。

solr用普通方法處理查詢結果

這個方法不是常用,因為在solr的軟體裡都有對應的查詢功能,只不過這裡把軟體轉換成Java程式碼了,話不多說,現在來看看具體程式碼,只瞭解一下即可。

程式碼如下:

複製程式碼

 1 package solrPublicToQueryPackage;
 2 
 3 import java.io.IOException;
 4 
 5 import org.apache.solr.client.solrj.SolrQuery;
 6 import org.apache.solr.client.solrj.SolrQuery.ORDER;
 7 import org.apache.solr.client.solrj.SolrServerException;
 8 import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
 9 import org.apache.solr.client.solrj.impl.HttpSolrServer;
10 import org.apache.solr.client.solrj.impl.XMLResponseParser;
11 import org.apache.solr.client.solrj.response.QueryResponse;
12 import org.apache.solr.common.SolrDocument;
13 import org.apache.solr.common.params.ModifiableSolrParams;
14 
15 //普通方式處理查詢結果 
16 public class solrPublicQuery {
17 
18       public static final String SOLR_URL = "http://localhost:8080/solr";
19 
20     public static void main(String[] args) throws SolrServerException, IOException {
21 
22          HttpSolrServer server = new HttpSolrServer(SOLR_URL);
23 
24             server.setMaxRetries(1);
25             server.setMaxRetries(1); // defaults to 0. > 1 not recommended.
26          server.setConnectionTimeout(5000); // 5 seconds to establish TCP
27 
28 
29           //正常情況下,以下引數無須設定
30             //使用老版本solrj操作新版本的solr時,因為兩個版本的javabin incompatible,所以需要設定Parser
31          server.setParser(new XMLResponseParser());
32             server.setSoTimeout(1000); // socket read timeout
33          server.setDefaultMaxConnectionsPerHost(100);
34          server.setMaxTotalConnections(100);
35             server.setFollowRedirects(false); // defaults to false
36 
37 
38             // allowCompression defaults to false.
39             // Server side must support gzip or deflate for this to have any effect.
40             server.setAllowCompression(true);
41 
42          //1、使用ModifiableSolrParams傳遞引數
43 
44         ModifiableSolrParams params = new ModifiableSolrParams();
45 
46         //192.168.230.128:8983/solr/select?q=video&fl=id,name,price&sort=price asc&start=0&rows=2&wt=json
47         // 設定引數,實現上面URL中的引數配置
48 
49         // 查詢關鍵詞
50 //      params.set("q", "name");
51 
52 //      // 返回資訊 
53 //      params.set("fl", "id,name,price,price_c");
54 
55 //      // 排序
56 //      params.set("sort", "price asc");
57 
58 //      // 分頁,start=0就是從0開始,rows=5當前返回5條記錄,第二頁就是變化start這個值為5就可以了
59 //      params.set("start", 2);
60 //      params.set("rows", 2);
61 
62 //      // 返回格式
63 //      params.set("wt", "javabin");
64 //      QueryResponse response = server.query(params);
65 
66           //2、使用SolrQuery傳遞引數,SolrQuery的封裝性更好
67             server.setRequestWriter(new BinaryRequestWriter());
68 
69          SolrQuery query = new SolrQuery();
70             query.setQuery("name");
71             query.setFields("id","name","price","price_c");
72             query.setSort("price", ORDER.asc);
73             query.setStart(0);
74             query.setRows(2);
75         query.setRequestHandler("/select");
76 
77           QueryResponse response = server.query(query);
78 
79 
80 
81          // 搜尋得到的結果數
82          System.out.println("Find:" + response.getResults().getNumFound());
83 
84         // 輸出結果
85             int iRow = 1;
86 
87             for (SolrDocument doc : response.getResults()) {
88 
89              System.out.println("----------" + iRow + "------------");
90             System.out.println("id: " + doc.getFieldValue("id").toString());
91             System.out.println("name: " + doc.getFieldValue("name").toString());
92             System.out.println("price: "
93                     + doc.getFieldValue("price").toString());
94             System.out.println("price_c: " + doc.getFieldValue("price_c"));
95             iRow++;
96                  }
97       }
98 
99 }

複製程式碼

 

順便提一下,看見標有1、2兩種方法的查詢方式都是可以用的,但是方法2是最佳方案;

熟悉完程式碼之後,大家在看看solr軟體,是不是這裡的好多設定和軟體是一樣的 ,只不過是程式碼而已。

以上程式碼只供瞭解,用程式碼查詢,大多數用的是POJO的處理查詢結果,下面就來介紹一下用POJO怎樣來處理查詢結果?

solr用POJO處理查詢結果

複製程式碼

 1 package solrPOJODealWithQueryResult;
 2 
 3 import java.io.IOException;
 4 import java.util.List;
 5 
 6 import org.apache.solr.client.solrj.SolrQuery;
 7 import org.apache.solr.client.solrj.SolrServerException;
 8 import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
 9 import org.apache.solr.client.solrj.impl.HttpSolrServer;
10 import org.apache.solr.client.solrj.response.FacetField;
11 import org.apache.solr.client.solrj.response.QueryResponse;
12 import org.apache.solr.common.SolrDocument;
13 import org.apache.solr.common.SolrDocumentList;
14 
15 import solrPOJOPackage.NewsBean;
16 
17 //採用POJOs方式處理查詢結果 
18 public class solrPOJODealWithResult {
19 
20      public static final String SOLR_URL = "http://localhost:8080/solr";
21 
22      public static void main(String[] args) throws SolrServerException, IOException {
23 
24          // http://172.168.63.233:8983/solr/collection1/select?q=description%3A%E6%80%BB%E7%9B%AE%E6%A0%87&facet=true&facet.field=author_s
25         HttpSolrServer server = new HttpSolrServer(SOLR_URL);
26 
27         server.setMaxRetries(1);