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);
28         server.setMaxRetries(1); // defaults to 0. > 1 not recommended.[,rekə'mendɪd]
29         server.setConnectionTimeout(5000); // 5 seconds to establish [ɪ'stæblɪʃ; e-] (創立)TCP
30         // server.setRequestWriter(new BinaryRequestWriter());
31         SolrQuery query = new SolrQuery();
32         query.setQuery("description:改革");
33         query.setStart(0);
34          query.setRows(2);
35         query.setFacet(true);
36         query.addFacetField("author_s");
37 
38         QueryResponse response = server.query(query);
39         // 搜索得到的結果數
40         System.out.println("Find:" + response.getResults().getNumFound()+"毫秒");
41         // 輸出結果
42         int iRow = 1;
43 
44         //response.getBeans存在BUG,將DocumentObjectBinder引用的Field應該為 org.apache.solr.client.solrj.beans.Field
45         SolrDocumentList list = response.getResults();
46          DocumentObjectBinder binder = new DocumentObjectBinder();
47         List<NewsBean> beanList=binder.getBeans(NewsBean.class, list);
48         for(NewsBean news:beanList){
49                 System.out.println("news的ID為:"+news.getId());
50         }
51 
52         for (SolrDocument doc : response.getResults()) {
53              System.out.println("----------" + iRow + "------------");
54                 System.out.println("id: " + doc.getFieldValue("id").toString());
55                  System.out.println("name: " + doc.getFieldValue("name").toString());
56               iRow++;
57         }
58         for (FacetField ff : response.getFacetFields()) {
59                 System.out.println(ff.getName() + "," + ff.getValueCount() + ","
60                         + ff.getValues());
61         }
62      }
63 
64 }

 

 

在打印台的效果演示: 
這里寫圖片描述

在solr服務器上查詢,順便驗證一下: 
這里寫圖片描述

結果證明了:

我的查找是正確,所以,在大多數常態下,會用到的就是solr,相比較Lucene來說,

solr是不是更加的強大呢?

以上就是我的solr介紹的全部內容,希望可以幫到大家,有什么不足的地方,希望大家能夠共同進步!

最后給大家提供一些別的博客地址: 
1、solr和zookepper的集群:訪問http://www.iigrowing.cn/solr-zong-jie.html

2、tomcat和solr的集成:訪問http://www.tuicool.com/articles/uAzQnaz

 

原文地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM