Solr調研總結php
1. Solr 是什麼?Solr它是一種開放源碼的、基於 Lucene Java 的搜索服務器,易於加入到 Web 應用程序中。Solr 提供了層面搜索(就是統計)、命中醒目顯示而且支持多種輸出格式(包括XML/XSLT 和JSON等格式)。它易於安裝和配置,並且附帶了一個基於HTTP 的管理界面。可使用 Solr 的表現優異的基本搜索功能,也能夠對它進行擴展從而知足企業的須要。Solr的特性包括:
2. Lucene 是什麼?Lucene是一個基於Java的全文信息檢索工具包,它不是一個完整的搜索應用程序,而是爲你的應用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta(雅加達) 家族中的一個開源項目。也是目前最爲流行的基於Java開源全文檢索工具包。目前已經有不少應用程序的搜索功能是基於 Lucene ,好比Eclipse 幫助系統的搜索功能。Lucene可以爲文本類型的數據創建索引,因此你只要把你要索引的數據格式轉化的文本格式,Lucene 就能對你的文檔進行索引和搜索。 3. Solr vs LuceneSolr與Lucene 並非競爭對立關係,偏偏相反Solr 依存於Lucene,由於Solr底層的核心技術是使用Lucene 來實現的,Solr和Lucene的本質區別有如下三點:搜索服務器,企業級和管理。Lucene本質上是搜索庫,不是獨立的應用程序,而Solr是。Lucene專一於搜索底層的建設,而Solr專一於企業應用。Lucene不負責支撐搜索服務所必須的管理,而Solr負責。因此說,一句話歸納 Solr: Solr是Lucene面向企業搜索應用的擴展。 Solr與Lucene架構圖:
Solr使用Lucene而且擴展了它!
Solr和Lucene這兩個一樣的索引,查詢中國: solr用時:0.073(秒) Lucene用時:1.071(秒) 4.搭建並調試Solr4.1 安裝虛擬機Solr 必須運行在Java1.6 或更高版本的Java 虛擬機中,運行標準Solr 服務只須要安裝JRE 便可,但若是須要擴展功能或編譯源碼則須要下載JDK 來完成。能夠經過下面的地址下載所需JDK 或JRE :
安裝 步驟請參考相應的幫助文檔。 4.2下載Solr本文針對Solr4.2版本進行調研的,下文介紹內容均針對Solr4.2版本,如與Solr 最新版本有出入請以官方網站內容爲準。Solr官方網站下載地址:http://lucene.apache.org/solr/ 4.3下載並設置Apache AntSolr是使用Ant進行管理的源碼, Ant是一種基於Java的build工具。理論上來講,它有些相似於Maven 或者是 C中的make。下載後解壓出來後,進行環境變量設置。 ANT_HOME:E:\Work\apache-ant\1.9.1 (這裏爲你本身解壓縮的目錄) PATH:%ANT_HOME%\bin (這個設置是爲了方便在dos環境下操做) 查看是否安裝成功,在命令行窗口中輸入命令ant,若出現結果:
其它的先不用管它,咱們只要針對咱們使用的IDE進行build就好了,若是使用eclipse就在命令行輸入:ant eclipse.若是使用IntelliJ IDEA 就在命令行輸入:ant idea。這樣就能進行build了。 黑窗口裏提示這個。。。
失敗。。。爲何呢,最後我發現是由於下載的ant中少了一個jar就是這apache-ivy(下載地址:http://ant.apache.org/ivy/)這東東名子真怪 ivy是ant管理jar依賴關係的。當第一次bulid時ivy會自動把build中的缺乏的依賴進行下載。網速慢的第一次build要很久的。。。 下載一個jar就行把jar放到ant的lib下(E:\Work\apache-ant\1.9.1\lib)這樣再次運行ant 就會成功了。到如今才能夠進行Solr的代碼調試。 4.4配置並運行Solr代碼無論用什麼IDE首選都要設置Solr Home在IDE的JVM參數設置VM arguments寫入 -Dsolr.solr.home=solr/example/solr通常就好了.不行也可使用絕對路徑. solr使用StartSolrJetty文件做爲入口文件進行調試代碼,在這裏能夠設置服務器使用的端口和solr的webapps目錄.通常都不用設置,默認的就能夠進行調試.Solr Home也能可在代碼中設置同樣好用. System.setProperty("solr.solr.home", "E:\\Work\\solr-4.2.0-src-idea\\solr\\example\\solr"); 目前是使用自帶的一個example做爲solr配置的根目錄,若是你有其餘的solr配置目錄,設置之便可。點擊run便可,debug也是同樣能夠用了。沒有別的問題就應該能運行了.注意servlet 容器使用的端口,如查提示: FAILED SocketConnector@0.0.0.0:8983: java.net.BindException: Address already in use: JVM_Bind 就說明當前端口占用中.改一下就能夠了.若是沒有報錯啓動成功後就能夠在瀏覽器中輸入地址: http://localhost:8983/solr/ 就能夠看到以下界面
到這裏Solr就成功配置並運行了.要是想跟代碼調試在啓動時在這個方法裏點斷點就能夠Initializer的initialize()方法若是想從瀏覽器中找斷點調試就要到SolrDispatchFilter的doFilter方法中點斷點了. 注:IE9在兼容模式下有bug,必須設置爲非兼容模式。 5.Solr基礎由於 Solr 包裝並擴展了Lucene,因此它們使用不少相同的術語。更重要的是,Solr 建立的索引與 Lucene 搜索引擎庫徹底兼容。經過對 Solr 進行適當的配置,某些狀況下可能須要進行編碼,Solr 能夠閱讀和使用構建到其餘 Lucene 應用程序中的索引。在 Solr 和 Lucene 中,使用一個或多個 Document 來構建索引。Document 包括一個或多個 Field。Field 包括名稱、內容以及告訴 Solr 如何處理內容的元數據。 例如,Field 能夠包含字符串、數字、布爾值或者日期,也能夠包含你想添加的任何類型,只需用在solr的配置文件中進行相應的配置便可。Field 可使用大量的選項來描述,這些選項告訴 Solr 在索引和搜索期間如何處理內容。 如今,查看一下表 1 中列出的重要屬性的子集:
5.1模式配置Schema.xmlschema.xml這個配置文件能夠在你下載solr包的安裝解壓目錄的\solr\example\solr\collection1\conf中找到,它就是solr模式關聯的文件。打開這個配置文件,你會發現有詳細的註釋。模式組織主要分爲三個重要配置 5.1.1. types 部分 是一些常見的可重用定義,定義了 Solr(和 Lucene)如何處理 Field。也就是添加到索引中的xml文件屬性中的類型,如int、text、date等.
參數說明:
5.1.2. fileds 是你添加到索引文件中出現的屬性名稱,而聲明類型就須要用到上面的types
還有一個特殊的字段copyField,通常用於檢索時用的字段這樣就只對這一個字段進行索引分詞就好了copyField的dest字段若是有多個source必定要設置multiValued=true,不然會報錯的
字段屬性說明:
注意:_version_ 是一個特殊字段,不能刪除,是記錄當前索引版本號的. 5.1.3. 其餘配置 uniqueKey: 惟一鍵,這裏配置的是上面出現的fileds,通常是id、url等不重複的。在更新、刪除的時候能夠用到。 defaultSearchField:默認搜索屬性,如q=solr就是默認的搜索那個字段 solrQueryParser:查詢轉換模式,是而且仍是或者(AND/OR必須大寫) 5.2. solr配置solrconfig.xmlsolrconfig.xml這個配置文件能夠在你下載solr包的安裝解壓目錄的E:\Work\solr-4.2.0-src-idea\solr\example\solr\collection1\conf中找到,這個配置文件內容有點多,主要內容有:使用的lib配置,包含依賴的jar和Solr的一些插件;組件信息配置;索引配置和查詢配置,下面詳細說一下索引配置和查詢配置. 5.2.1索引indexConfig Solr 性能因素,來了解與各類更改相關的性能權衡。 表 1 歸納了可控制 Solr 索引處理的各類因素:
5.2.2 查詢配置query
5.3Solr加入中文分詞器中文分詞在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中.
5.3.1. 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定義的那一段,在下面多添加這一段就好啦
若是須要檢索某個字段,還須要在scheme.xml下面的field中,添加指定的字段,用text_ smartcn做爲type的名字,來完成中文分詞。如 text要實現中文檢索的話,就要作以下的配置:
5.3.2. IK 分詞器的安裝 首選要去下載IKAnalyzer的發行包.下載地址: 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了.
如今來驗證下是否添加成功,首先使用StartSolrJetty來啓動solr服務,啓動過程當中若是配置出錯,通常有兩個緣由:一是配置的分詞器jar找不到,也就是你沒有複製jar包到\solr\contrib\analysis-extras\lib目前下;二是分詞器版本不對致使的分詞器接口API不同出的錯,要是這個錯的話就在檢查分詞器的相關文檔,看一下支持的版本是否同樣. 若是在啓動過程當中沒有報錯的話說明配置成功了.咱們能夠進入到http://localhost:8983/solr地址進行測試一下剛加入的中文分詞器.在首頁的Core Selector中選擇你配置的Croe後點擊下面的Analysis,在Analyse Fieldname / FieldType裏選擇你剛纔設置的字段名稱或是分詞器類型,在Field Value(index)中輸入:中國人,點擊右面的分詞就好了.
6.Solr功能應用我這裏主要使用SolrJ進行介紹一下Solr的一些基本應用,使用SolrJ加上EmbeddedSolrServer(嵌入式服務器),方便進行代碼跟蹤調試.在功能上和其它服務器都是同樣的,它們都是繼承的SolrServer來提供服務API的. EmbeddedSolrServer優勢是不用起http協議,直接加載SolrCore進行操做,性能上應該是最快的,方便用於把Solr單結點服務嵌入到項目中使用.下面開始介紹Solr的功能的應用.EmbeddedSolrServer初始化:
6.1維護索引在通常系統中維護的都是增刪改,在Solr中的維護功能是增刪和優化功能,在Solr中的修改操做就是先刪掉再添加.在作索引維護以前,首先要作的是配置schema.xml主要是按上面章節中的說明設置好字段信息(名稱,類型,索引,存儲,分詞等信息),大概就像在數據庫中新建一個表同樣.設置好schema.xml就能夠進行索引相關操做了. 6.1.1增長索引 在增長索引以前先可構建好SolrInputDocument對象.主要操做就是給文檔添加字段和值.代碼以下:
構建好文檔後添加的上面初始化好的server裏就好了.
Solr在add文檔時.若是文檔不存在就直接添加,若是文檔存在就刪除後添加,這也就是修改功能了.判斷文檔是否存在的依據是定義好的uniqueKey字段. 6.1.2刪除索引 刪除索引能夠經過兩種方式操做,一種是經過文檔ID進行刪除,別一種是經過查詢到的結果進行刪除. 經過ID刪除方式代碼:
經過查詢刪除方式代碼:
6.1.2優化索引 優化Lucene 的索引文件以改進搜索性能。索引完成後執行一下優化一般比較好。若是更新比較頻繁,則應該在使用率較低的時候安排優化。一個索引無需優化也能夠正常地運行。優化是一個耗時較多的過程。
6.2文本檢索Solr在不修改任務配置的狀況下就可使用文本檢索功能,在web項目中應用能夠直接URL進行訪問Solr服務器例如 :
上面的意思就是檢索名爲collection1的SolrCore的全部內容用xml格式返回而且有縮進。 返回結果以下:
上面所看到的就是用xml格式返回的查詢結果,其中的doc就是一個文檔,在doc裏面的那個就是咱們開始在schema.xml中定義的字段. 若是使用SolrJ進行調用的話代碼以下:
返回結果在SolrDocumentList中在這個對象中遍歷取出值來:
6.2.1查詢參數
6.2.2查詢語法 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的。 4. 子表達式查詢(子查詢):可使用「()」構造子查詢。 示例:(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.五、make-believ~0.八、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年前前一天的這個時間 6.2.3函數查詢(Function Query) 函數查詢 能夠利用 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 2. 函數的格式(Function Query Syntax) 目前,function query 並不支持 a+b 這樣的形式,咱們得把它寫成一個方法形式,這就是 sum(a,b). 3. 使用函數查詢注意事項 1) 用於函數查詢的field必須是被索引的; 2) 字段不能夠是多值的(multi-value) 4. 能夠利用的函數 (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) 6.3高亮顯示咱們常用搜索引擎,好比在baidu 搜索 java ,會出現以下結果,結果中與關鍵字匹配的地方是紅色顯示與其餘內容區別開來。
solr 默認已經配置了highlight 組件(詳見 SOLR_HOME/conf/sorlconfig.xml)。一般我出只須要這樣請求http://localhost:8983/solr/ collection1 /select? q=%E4%B8%AD%E5%9B%BD&start=0&rows=1&fl=content+path+&wt=xml&indent=true&hl=true&hl.fl=content 能夠看到與比通常的請求多了兩個參數 "hl=true" 和 "hl.fl= content " 。 "hl=true" 是開啓高亮,"hl.fl= content " 是告訴solr 對 name 字段進行高亮(若是你想對多個字段進行高亮,能夠繼續添加字段,字段間用逗號隔開,如 "hl.fl=name,name2,name3")。 高亮內容與關鍵匹配的地方,默認將會被 "<em>" 和 "</em>" 包圍。還可使用hl.simple.pre" 和 "hl.simple.post"參數設置先後標籤. 查詢結果以下:
使用SolrJ方法基本同樣也是設置這些個參數,只不過是SolrJ封裝起來了,代碼以下:
6.4拼寫檢查首先配置 solrconfig.xml,文件可能已經有這兩個元素(若是沒有添加便可),須要根據咱們本身的系統環境作些適當的修改。
配置完成以後,咱們進行一下測試,重啓Solr後,訪問以下連接
使用SolrJ時也一樣加入參數就能夠
6.5檢索建議檢索建議目前是各大搜索的標配應用,主要做用是避免用戶輸入錯誤的搜索詞,同時將用戶引導到相應的關鍵詞搜索上。Solr內置了檢索建議功能,它在Solr裏叫作Suggest模塊.該模塊可選擇基於提示詞文本作檢索建議,還支持經過針對索引的某個字段創建索引詞庫作檢索建議。在諸多文檔中都推薦使用基於索引來作檢索建議,所以咱們目前的實現也是採起該方案。 如今咱們開始配置Suggest模塊,首先在solrconfig.xml文件中配置Suggest依賴的SpellChecker模塊,而後再配置Suggest模塊,因此這兩個都須要配置。
配置完成以後,咱們進行一下測試,重啓Solr後,訪問以下連接
使用SolrJ時也一樣加入參數就能夠
經過threshold參數來限制一些不經常使用的詞不出如今智能提示列表中,當這個值設置過大時,可能致使結果太少,須要引發注意。目前主要存在的問題是使用freq排序算法,返回的結果徹底基於索引中字符的出現次數,沒有兼顧用戶搜索詞語的頻率,所以沒法將一些熱門詞排在更靠前的位置。這塊可定製SuggestWordScoreComparator來實現,目前尚未着手作這件事情。 6.6分組統計我這裏實現分組統計的方法是使用了Solr的Facet組件, Facet組件是Solr默認集成的一個組件. 6.6.1 Facet簡介 Facet是solr的高級搜索功能之一,能夠給用戶提供更友好的搜索體驗.在搜索關鍵字的同時,可以按照Facet的字段進行分組並統計
6.6.2 Facet字段 1. 適宜被Facet的字段 通常表明了實體的某種公共屬性,如商品的分類,商品的製造廠家,書籍的出版商等等. 2. Facet字段的要求 Facet的字段必須被索引.通常來講該字段無需分詞,無需存儲. 無需分詞是由於該字段的值表明了一個總體概念,如電腦的品牌」聯想」表明了一個整 體概念,若是拆成」聯」,」想」兩個字都不具備實際意義.另外該字段的值無需進行大小 寫轉換等處理,保持其原貌便可. 無需存儲是由於通常而言用戶所關心的並非該字段的具體值,而是做爲對查詢結果進 行分組的一種手段,用戶通常會沿着這個分組進一步深刻搜索. 3. 特殊狀況 對於通常查詢而言,分詞和存儲都是必要的.好比CPU類型」Intel 酷睿2雙核 P7570」, 拆分紅」Intel」,」酷睿」,」P7570」這樣一些關鍵字並分別索引,可能提供更好的搜索 體驗.可是若是將CPU做爲Facet字段,最好不進行分詞.這樣就形成了矛盾,解決方法爲, 將CPU字段設置爲不分詞不存儲,而後創建另一個字段爲它的COPY,對這個COPY的 字段進行分詞和存儲.
6.6.2 Facet組件 Solr的默認requestHandler已經包含了Facet組件(solr.FacetComponent).若是自定義requestHandler或者對默認的requestHandler自定義組件列表,那麼須要將Facet加入到組件列表中去.
6.6.2 Facet查詢 進行Facet查詢須要在請求參數中加入facet=on或者facet=true只有這樣Facet組件才起做用. 1. Field Facet Facet字段經過在請求中加入facet.field參數加以聲明,若是須要對多個字段進行Facet查詢,那麼將該參數聲明屢次.例如: 返回結果:
各個Facet字段互不影響,且能夠針對每一個Facet字段設置查詢參數.如下介紹的參數既能夠應用於全部的Facet字段,也能夠應用於每一個單獨的Facet字段.應用於單獨的字段時經過
這種方式調用.好比facet.prefix參數應用於cpu字段,能夠採用以下形式
1.1 facet.prefix 表示Facet字段值的前綴.好比facet.field=cpu&facet.prefix=Intel,那麼對cpu字段進行Facet查詢,返回的cpu都是以Intel開頭的, AMD開頭的cpu型號將不會被統計在內. 1.2 facet.sort 表示Facet字段值以哪一種順序返回.可接受的值爲true(count)|false(index,lex). true(count)表示按照count值從大到小排列. false(index,lex)表示按照字段值的天然順序(字母,數字的順序)排列.默認狀況下爲true(count).當facet.limit值爲負數時,默認facet.sort= false(index,lex). 1.3 facet.limit 限制Facet字段返回的結果條數.默認值爲100.若是此值爲負數,表示不限制. 1.4 facet.offset 返回結果集的偏移量,默認爲0.它與facet.limit配合使用能夠達到分頁的效果. 1.5 facet.mincount 限制了Facet字段值的最小count,默認爲0.合理設置該參數能夠將用戶的關注點集中在少數比較熱門的領域. 1.6 facet.missing 默認爲」」,若是設置爲true或者on,那麼將統計那些該Facet字段值爲null的記錄. 1.7 facet.method 取值爲enum或fc,默認爲fc.該字段表示了兩種Facet的算法,與執行效率相關. enum適用於字段值比較少的狀況,好比字段類型爲布爾型,或者字段表示中國的全部省份.Solr會遍歷該字段的全部取值,並從filterCache裏爲每一個值分配一個filter(這裏要求solrconfig.xml裏對filterCache的設置足夠大).而後計算每一個filter與主查詢的交集. fc(表示Field Cache)適用於字段取值比較多,但在每一個文檔裏出現次數比較少的狀況.Solr會遍歷全部的文檔,在每一個文檔內搜索Cache內的值,若是找到就將Cache內該值的count加1. 1.8 facet.enum.cache.minDf 當facet.method=enum時,此參數其做用,minDf表示minimum document frequency.也就是文檔內出現某個關鍵字的最少次數.該參數默認值爲0.設置該參數能夠減小filterCache的內存消耗,但會增長總的查詢時間(計算交集的時間增長了).若是設置該值的話,官方文檔建議優先嚐試25-50內的值. 6.6.3 Date Facet 日期類型的字段在文檔中很常見,如商品上市時間,貨物出倉時間,書籍上架時間等等.某些狀況下須要針對這些字段進行Facet.不過期間字段的取值有無限性,用戶每每關心的不是某個時間點而是某個時間段內的查詢統計結果. Solr爲日期字段提供了更爲方便的查詢統計方式.固然,字段的類型必須是DateField(或其子類型). 須要注意的是,使用Date Facet時,字段名,起始時間,結束時間,時間間隔這4個參數都必須提供.與Field Facet相似,Date Facet也能夠對多個字段進行Facet.而且針對每一個字段均可以單獨設置參數. facet.date:該參數表示須要進行Date Facet的字段名,與facet.field同樣,該參數能夠被設置屢次,表示對多個字段進行Date Facet. facet.date.start:起始時間,時間的通常格式爲1995-12-31T23:59:59Z,另外可使用NOW\YEAR\ MONTH等等,具體格式能夠參考DateField的java doc. facet.date.end:結束時間. facet.date.gap:時間間隔.若是start爲2009-1-1,end爲2010-1-1.gap設置爲+1MONTH表示間隔1個月,那麼將會把這段時間劃分爲12個間隔段. 注意+由於是特殊字符因此應該用%2B代替. facet.date.hardend:取值能夠爲true|false,默認爲false.它表示gap迭代到end處採用何種處理.舉例說明start爲2009-1-1,end爲2009-12-25,gap爲+1MONTH, hardend爲false的話最後一個時間段爲2009-12-1至2010-1-1; hardend爲true的話最後一個時間段爲2009-12-1至2009-12-25. facet.date.other:取值範圍爲before|after|between|none|all,默認爲none.before會對start以前的值作統計.after會對end以後的值作統計.between會對start至end之間全部值作統計.若是hardend爲true的話,那麼該值就是各個時間段統計值的和.none表示該項禁用.all表示before,after,all都會統計. 舉例:
返回結果:
6.6.4 Facet Query Facet Query利用相似於filter query的語法提供了更爲靈活的Facet.經過facet.query參數,能夠對任意字段進行篩選. 例1:
返回結果:
例2:
返回結果:
例3:
返回結果:
6.6.5 key操做符 能夠用key操做符爲Facet字段取一個別名. 例:
返回結果:
6.6.6 tag操做符和ex操做符 當查詢使用filter query的時候,若是filter query的字段正好是Facet字段,那麼查詢結果每每被限制在某一個值內. 例:
返回結果:
能夠看到,屏幕尺寸(screenSize)爲14寸的產品共有107件,其它尺寸的產品的數目都是0,這是由於在filter裏已經限制了screenSize:14.這樣,查詢結果中,除了screenSize=14的這一項以外,其它項目沒有實際的意義.有些時候,用戶但願把結果限制在某一範圍內,又但願查看該範圍外的概況.好比上述狀況,既要把查詢結果限制在14寸屏的筆記本,又想查看一下其它屏幕尺寸的筆記本有多少產品.這個時候須要用到tag和ex操做符.tag就是把一個filter標記起來,ex(exclude)是在Facet的時候把標記過的filter排除在外. 例:
返回結果:
這樣其它屏幕尺寸的統計信息就有意義了. 6.6.7 SolrJ對Facet的支持
6.7自動聚類Solr 使用Carrot2完成了聚類功能,可以把檢索到的內容自動分類, Carrot2聚類示例:
要想Solr支持聚類功能,首選要把Solr發行包的中的dist/ solr-clustering-4.2.0.jar, 複製到\solr\contrib\analysis-extras\lib下.而後打開solrconfig.xml進行添加配置:
配好了聚類組件後,下面配置requestHandler:
有兩個參數要注意carrot.title, carrot.snippet是聚類的比較計算字段,這兩個參數必須是stored="true".carrot.title的權重要高於carrot.snippet,若是隻有一個作計算的字段carrot.snippet能夠去掉(是去掉不是值爲空).設完了用下面的URL就能夠查詢了 http://localhost:8983/skyCore/clustering?q=*%3A*&wt=xml&indent=true 6.8類似匹配在咱們使用網頁搜索時,會注意到每個結果都包含一個 「類似頁面」 連接,單擊該連接,就會發布另外一個搜索請求,查找出與起初結果相似的文檔。Solr 使用 MoreLikeThisComponent(MLT)和 MoreLikeThisHandler 實現了同樣的功能。如上所述,MLT 是與標準 SolrRequestHandler 集成在一塊兒的;MoreLikeThisHandler 與 MLT 結合在一塊兒,並添加了一些其餘選項,但它要求發佈一個單一的請求。我將着重講述 MLT,由於使用它的可能性更大一些。幸運的是,不須要任何設置就能夠查詢它,因此您如今就能夠開始查詢。 MLT 要求字段被儲存或使用檢索詞向量,檢索詞向量以一種以文檔爲中心的方式儲存信息。MLT 經過文檔的內容來計算文檔中關鍵詞語,而後使用原始查詢詞語和這些新詞語建立一個新的查詢。提交新查詢就會返回其餘查詢結果。全部這些均可以用檢索詞向量來完成:只需將 termVectors="true" 添加到 schema.xml 中的 <field> 聲明。 MoreLikeThisComponent 參數:
要想使用匹配類似首先在 solrconfig.xml 中配置 MoreLikeThisHandler
而後我就能夠請求 上面請求的意思查找 id 爲 6F398CCD-2DE0-D3B1-9DD6-D4E532FFC531 的 document ,而後返回與此 document 在 name 字段上類似的其餘 document。須要注意的是 mlt.fl 中的 field 的 termVector=true 纔有效果
使用SolrJ時也一樣加入參數就能夠
6.9拼音檢索拼音檢索中國人的專用檢索,例如:中文內容爲 中國 的輸入zhongguo、zg、zhonggu 全拼、簡拼、拼音的相鄰的一部份都應該能檢索出 中國 來。 想要實現拼音檢索第一個就是拼音轉換我這裏用的是pinyin4j進行拼音轉換。第二個就是N-Gram的題目,推敲到用戶可能輸入的既不是前綴也不是後綴,因此此處選擇的是N-Gram技巧,但不一樣於經常使用的N-Gram,我應用的從一邊開端的單向的N-Gram,Solr裏的實現叫EdgeNGramTokenFilter,可是分的分的太細了,不須要這麼複雜EdgeNGramTokenFilter,也就是說咱們用的N-Gram不一樣於傳統的N-Gram。 一樣的例子使用EdgeNGramTokenFilter從前日後取2-Gram的結果是zh, 通常是取min–max之間的全部gram,因此使用EdgeNGramTokenFilter取2-20的gram結果就是zh,zho, zhon, zhong, zhongg, zhonggu, zhongguo, 從這個例子也不難理解爲何我要選擇使用EdgeNGramTokenFilter而非通常意義上的N-Gram, 考慮到用戶可能輸入的不是前綴而是後綴,因此爲了照顧這些用戶,我選擇了從前日後和從後往前使用了兩次EdgeNGramTokenFilter,這樣不僅是前綴、後綴,二十任意的字串都考慮進去了,因此大幅度的提升了搜索體驗. 如今思路明確了咱們把它結合到Solr中,爲了方便使用如今寫了兩個Filter進行處理拼音分詞問題一個是拼音轉換Filter(PinyinTransformTokenFilter)一個是拼音N-Gram的Filter(PinyinNGramTokenFilter),這樣一來使用時就不用在添加索引前作攔音的轉換了。並且PinyinTransformTokenFilter還有個好處就是它只使用中文分詞器分過的詞,也就是說作轉換的詞都是有用的不重複的,不會對沒用的停詞類的作拼音轉換和重複拼音轉換,這樣大大的提升了拼音轉換速度。 想要Solr支持拼音檢索就要先把拼音分詞(PinyinAnalyzer)的jar複製到\solr\contrib\analysis-extras\lib下,而後在schema.xml中配置一個拼音字段類型:
minTermLenght:最小中文詞長度,意思是小於這個值的中文詞不會作拼音轉換。 minGram:最小拼音切分長度。 在這個拼音類型中咱們使用了smartcn的中言語分詞器,若是想使用其它的本身換掉就好了。如今咱們在原來索引中加入一個拼音字段,由於只作索引,咱們能夠這樣配置:
加完後咱們從新啓動Solr測試一下看看
因爲上面minTermLenght和minGram設置的值,如今出現了人沒有進行拼音轉換而且最小拼音切分是從1個開始的。 到這裏咱們的配置還有沒完成呢,還要加幾個copyFiled,這樣就不用單獨處理咱們新加的拼音字段了。方便呀~~~
到如今就可使用拼音檢索了。 我寫的拼音jar http://pan.baidu.com/share/link?shareid=2579170560&uk=4077294790 6.10 SolrCloudSolrCloud是基於Solr和Zookeeper的分佈式搜索方案,是正在開發中的Solr4.0的核心組件之一,它的主要思想是使用Zookeeper做爲集羣的配置信息中心。它有幾個特點功能,集中式的配置信息、自動容錯 、近實時搜索 、查詢時自動負載均衡。
基本能夠用上面這幅圖來概述,這是一個擁有4個Solr節點的集羣,索引分佈在兩個Shard裏面,每一個Shard包含兩個Solr節點,一個是Leader節點,一個是Replica節點,此外集羣中有一個負責維護集羣狀態信息的Overseer節點,它是一個總控制器。集羣的全部狀態信息都放在Zookeeper集羣中統一維護。從圖中還能夠看到,任何一個節點均可以接收索引更新的請求,而後再將這個請求轉發到文檔所應該屬於的那個Shard的Leader節點,Leader節點更新結束完成,最後將版本號和文檔轉發給同屬於一個Shard的replicas節點。這裏就很少說SolrCloud了,等研究明白後再單寫一個文檔。
附1:schema.xml
附2:solrconfig.xml
參考資料及文獻http://wiki.apache.org/solr/ 全部的配置在這裏都有說明 http://doc.carrot2.org/ 聚類相關設置在這裏有說明 轉自:http://www.cnblogs.com/DjangoBlog/p/3768027 |
如非特別註明,本站內容均爲領悟書生原創,轉載請務必註明做者和原始出處。
本文地址:http://www.656463.com/article/EZZnIv.htm
2014-12-16 23:18:12| 發佈: | 瀏覽: 2680
http://www.cnblogs.com/guozk/p/3498831.html
Solr調研總結
1. Solr 是什麼?Solr它是一種開放源碼的、基於 Lucene Java 的搜索服務器,易於加入到 Web 應用程序中。Solr 提供了層面搜索(就是統計)、命中醒目顯示而且支持多種輸出格式(包括XML/XSLT 和JSON等格式)。它易於安裝和配置,並且附帶了一個基於HTTP 的管理界面。可使用 Solr 的表現優異的基本搜索功能,也能夠對它進行擴展從而知足企業的須要。Solr的特性包括:
2. Lucene 是什麼?Lucene是一個基於Java的全文信息檢索工具包,它不是一個完整的搜索應用程序,而是爲你的應用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta(雅加達) 家族中的一個開源項目。也是目前最爲流行的基於Java開源全文檢索工具包。目前已經有不少應用程序的搜索功能是基於 Lucene ,好比Eclipse 幫助系統的搜索功能。Lucene可以爲文本類型的數據創建索引,因此你只要把你要索引的數據格式轉化的文本格式,Lucene 就能對你的文檔進行索引和搜索。 3. Solr vs LuceneSolr與Lucene 並非競爭對立關係,偏偏相反Solr 依存於Lucene,由於Solr底層的核心技術是使用Lucene 來實現的,Solr和Lucene的本質區別有如下三點:搜索服務器,企業級和管理。Lucene本質上是搜索庫,不是獨立的應用程序,而Solr是。Lucene專一於搜索底層的建設,而Solr專一於企業應用。Lucene不負責支撐搜索服務所必須的管理,而Solr負責。因此說,一句話歸納 Solr: Solr是Lucene面向企業搜索應用的擴展。 Solr與Lucene架構圖:
Solr使用Lucene而且擴展了它!
Solr和Lucene這兩個一樣的索引,查詢中國: solr用時:0.073(秒) Lucene用時:1.071(秒) 4.搭建並調試Solr4.1 安裝虛擬機Solr 必須運行在Java1.6 或更高版本的Java 虛擬機中,運行標準Solr 服務只須要安裝JRE 便可,但若是須要擴展功能或編譯源碼則須要下載JDK 來完成。能夠經過下面的地址下載所需JDK 或JRE :
安裝 步驟請參考相應的幫助文檔。 4.2下載Solr本文針對Solr4.2版本進行調研的,下文介紹內容均針對Solr4.2版本,如與Solr 最新版本有出入請以官方網站內容爲準。Solr官方網站下載地址:http://lucene.apache.org/solr/ 4.3下載並設置Apache AntSolr是使用Ant進行管理的源碼, Ant是一種基於Java的build工具。理論上來講,它有些相似於Maven 或者是 C中的make。下載後解壓出來後,進行環境變量設置。 ANT_HOME:E:\Work\apache-ant\1.9.1 (這裏爲你本身解壓縮的目錄) PATH:%ANT_HOME%\bin (這個設置是爲了方便在dos環境下操做) 查看是否安裝成功,在命令行窗口中輸入命令ant,若出現結果:
其它的先不用管它,咱們只要針對咱們使用的IDE進行build就好了,若是使用eclipse就在命令行輸入:ant eclipse.若是使用IntelliJ IDEA 就在命令行輸入:ant idea。這樣就能進行build了。 黑窗口裏提示這個。。。
失敗。。。爲何呢,最後我發現是由於下載的ant中少了一個jar就是這apache-ivy(下載地址:http://ant.apache.org/ivy/)這東東名子真怪 ivy是ant管理jar依賴關係的。當第一次bulid時ivy會自動把build中的缺乏的依賴進行下載。網速慢的第一次build要很久的。。。 下載一個jar就行把jar放到ant的lib下(E:\Work\apache-ant\1.9.1\lib)這樣再次運行ant 就會成功了。到如今才能夠進行Solr的代碼調試。 4.4配置並運行Solr代碼無論用什麼IDE首選都要設置Solr Home在IDE的JVM參數設置VM arguments寫入 -Dsolr.solr.home=solr/example/solr通常就好了.不行也可使用絕對路徑. solr使用StartSolrJetty文件做爲入口文件進行調試代碼,在這裏能夠設置服務器使用的端口和solr的webapps目錄.通常都不用設置,默認的就能夠進行調試.Solr Home也能可在代碼中設置同樣好用. System.setProperty("solr.solr.home", "E:\\Work\\solr-4.2.0-src-idea\\solr\\example\\solr"); 目前是使用自帶的一個example做爲solr配置的根目錄,若是你有其餘的solr配置目錄,設置之便可。點擊run便可,debug也是同樣能夠用了。沒有別的問題就應該能運行了.注意servlet 容器使用的端口,如查提示: FAILED SocketConnector@0.0.0.0:8983: java.net.BindException: Address already in use: JVM_Bind 就說明當前端口占用中.改一下就能夠了.若是沒有報錯啓動成功後就能夠在瀏覽器中輸入地址: http://localhost:8983/solr/ 就能夠看到以下界面
到這裏Solr就成功配置並運行了.要是想跟代碼調試在啓動時在這個方法裏點斷點就能夠Initializer的initialize()方法若是想從瀏覽器中找斷點調試就要到SolrDispatchFilter的doFilter方法中點斷點了. 注:IE9在兼容模式下有bug,必須設置爲非兼容模式。 5.Solr基礎由於 Solr 包裝並擴展了Lucene,因此它們使用不少相同的術語。更重要的是,Solr 建立的索引與 Lucene 搜索引擎庫徹底兼容。經過對 Solr 進行適當的配置,某些狀況下可能須要進行編碼,Solr 能夠閱讀和使用構建到其餘 Lucene 應用程序中的索引。在 Solr 和 Lucene 中,使用一個或多個 Document 來構建索引。Document 包括一個或多個 Field。Field 包括名稱、內容以及告訴 Solr 如何處理內容的元數據。 例如,Field 能夠包含字符串、數字、布爾值或者日期,也能夠包含你想添加的任何類型,只需用在solr的配置文件中進行相應的配置便可。Field 可使用大量的選項來描述,這些選項告訴 Solr 在索引和搜索期間如何處理內容。 如今,查看一下表 1 中列出的重要屬性的子集:
5.1模式配置Schema.xmlschema.xml這個配置文件能夠在你下載solr包的安裝解壓目錄的\solr\example\solr\collection1\conf中找到,它就是solr模式關聯的文件。打開這個配置文件,你會發現有詳細的註釋。模式組織主要分爲三個重要配置 5.1.1. types 部分 是一些常見的可重用定義,定義了 Solr(和 Lucene)如何處理 Field。也就是添加到索引中的xml文件屬性中的類型,如int、text、date等.
參數說明:
5.1.2. fileds 是你添加到索引文件中出現的屬性名稱,而聲明類型就須要用到上面的types
還有一個特殊的字段copyField,通常用於檢索時用的字段這樣就只對這一個字段進行索引分詞就好了copyField的dest字段若是有多個source必定要設置multiValued=true,不然會報錯的
字段屬性說明:
注意:_version_ 是一個特殊字段,不能刪除,是記錄當前索引版本號的. 5.1.3. 其餘配置 uniqueKey: 惟一鍵,這裏配置的是上面出現的fileds,通常是id、url等不重複的。在更新、刪除的時候能夠用到。 defaultSearchField:默認搜索屬性,如q=solr就是默認的搜索那個字段 solrQueryParser:查詢轉換模式,是而且仍是或者(AND/OR必須大寫) 5.2. solr配置solrconfig.xmlsolrconfig.xml這個配置文件能夠在你下載solr包的安裝解壓目錄的E:\Work\solr-4.2.0-src-idea\solr\example\solr\collection1\conf中找到,這個配置文件內容有點多,主要內容有:使用的lib配置,包含依賴的jar和Solr的一些插件;組件信息配置;索引配置和查詢配置,下面詳細說一下索引配置和查詢配置. 5.2.1索引indexConfig Solr 性能因素,來了解與各類更改相關的性能權衡。 表 1 歸納了可控制 Solr 索引處理的各類因素:
5.2.2 查詢配置query
5.3Solr加入中文分詞器中文分詞在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中.
5.3.1. 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定義的那一段,在下面多添加這一段就好啦
若是須要檢索某個字段,還須要在scheme.xml下面的field中,添加指定的字段,用text_ smartcn做爲type的名字,來完成中文分詞。如 text要實現中文檢索的話,就要作以下的配置:
5.3.2. IK 分詞器的安裝 首選要去下載IKAnalyzer的發行包.下載地址: 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了.
如今來驗證下是否添加成功,首先使用StartSolrJetty來啓動solr服務,啓動過程當中若是配置出錯,通常有兩個緣由:一是配置的分詞器jar找不到,也就是你沒有複製jar包到\solr\contrib\analysis-extras\lib目前下;二是分詞器版本不對致使的分詞器接口API不同出的錯,要是這個錯的話就在檢查分詞器的相關文檔,看一下支持的版本是否同樣. 若是在啓動過程當中沒有報錯的話說明配置成功了.咱們能夠進入到http://localhost:8983/solr地址進行測試一下剛加入的中文分詞器.在首頁的Core Selector中選擇你配置的Croe後點擊下面的Analysis,在Analyse Fieldname / FieldType裏選擇你剛纔設置的字段名稱或是分詞器類型,在Field Value(index)中輸入:中國人,點擊右面的分詞就好了.
6.Solr功能應用我這裏主要使用SolrJ進行介紹一下Solr的一些基本應用,使用SolrJ加上EmbeddedSolrServer(嵌入式服務器),方便進行代碼跟蹤調試.在功能上和其它服務器都是同樣的,它們都是繼承的SolrServer來提供服務API的. EmbeddedSolrServer優勢是不用起http協議,直接加載SolrCore進行操做,性能上應該是最快的,方便用於把Solr單結點服務嵌入到項目中使用.下面開始介紹Solr的功能的應用.EmbeddedSolrServer初始化:
6.1維護索引在通常系統中維護的都是增刪改,在Solr中的維護功能是增刪和優化功能,在Solr中的修改操做就是先刪掉再添加.在作索引維護以前,首先要作的是配置schema.xml主要是按上面章節中的說明設置好字段信息(名稱,類型,索引,存儲,分詞等信息),大概就像在數據庫中新建一個表同樣.設置好schema.xml就能夠進行索引相關操做了. 6.1.1增長索引 在增長索引以前先可構建好SolrInputDocument對象.主要操做就是給文檔添加字段和值.代碼以下:
構建好文檔後添加的上面初始化好的server裏就好了.
Solr在add文檔時.若是文檔不存在就直接添加,若是文檔存在就刪除後添加,這也就是修改功能了.判斷文檔是否存在的依據是定義好的uniqueKey字段. 6.1.2刪除索引 刪除索引能夠經過兩種方式操做,一種是經過文檔ID進行刪除,別一種是經過查詢到的結果進行刪除. 經過ID刪除方式代碼:
經過查詢刪除方式代碼:
6.1.2優化索引 優化Lucene 的索引文件以改進搜索性能。索引完成後執行一下優化一般比較好。若是更新比較頻繁,則應該在使用率較低的時候安排優化。一個索引無需優化也能夠正常地運行。優化是一個耗時較多的過程。
6.2文本檢索Solr在不修改任務配置的狀況下就可使用文本檢索功能,在web項目中應用能夠直接URL進行訪問Solr服務器例如 :
上面的意思就是檢索名爲collection1的SolrCore的全部內容用xml格式返回而且有縮進。 返回結果以下:
上面所看到的就是用xml格式返回的查詢結果,其中的doc就是一個文檔,在doc裏面的那個就是咱們開始在schema.xml中定義的字段. 若是使用SolrJ進行調用的話代碼以下:
返回結果在SolrDocumentList中在這個對象中遍歷取出值來:
6.2.1查詢參數
6.2.2查詢語法 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的。 4. 子表達式查詢(子查詢):可使用「()」構造子查詢。 示例:(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.五、make-believ~0.八、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年前前一天的這個時間 6.2.3函數查詢(Function Query) 函數查詢 能夠利用 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 2. 函數的格式(Function Query Syntax) 目前,function query 並不支持 a+b 這樣的形式,咱們得把它寫成一個方法形式,這就是 sum(a,b). 3. 使用函數查詢注意事項 1) 用於函數查詢的field必須是被索引的; 2) 字段不能夠是多值的(multi-value) 4. 能夠利用的函數 (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) 6.3高亮顯示咱們常用搜索引擎,好比在baidu 搜索 java ,會出現以下結果,結果中與關鍵字匹配的地方是紅色顯示與其餘內容區別開來。
solr 默認已經配置了highlight 組件(詳見 SOLR_HOME/conf/sorlconfig.xml)。一般我出只須要這樣請求http://localhost:8983/solr/ collection1 /select? q=%E4%B8%AD%E5%9B%BD&start=0&rows=1&fl=content+path+&wt=xml&indent=true&hl=true&hl.fl=content 能夠看到與比通常的請求多了兩個參數 "hl=true" 和 "hl.fl= content " 。 "hl=true" 是開啓高亮,"hl.fl= content " 是告訴solr 對 name 字段進行高亮(若是你想對多個字段進行高亮,能夠繼續添加字段,字段間用逗號隔開,如 "hl.fl=name,name2,name3")。 高亮內容與關鍵匹配的地方,默認將會被 "<em>" 和 "</em>" 包圍。還可使用hl.simple.pre" 和 "hl.simple.post"參數設置先後標籤. 查詢結果以下:
使用SolrJ方法基本同樣也是設置這些個參數,只不過是SolrJ封裝起來了,代碼以下:
6.4拼寫檢查首先配置 solrconfig.xml,文件可能已經有這兩個元素(若是沒有添加便可),須要根據咱們本身的系統環境作些適當的修改。
配置完成以後,咱們進行一下測試,重啓Solr後,訪問以下連接
使用SolrJ時也一樣加入參數就能夠
6.5檢索建議檢索建議目前是各大搜索的標配應用,主要做用是避免用戶輸入錯誤的搜索詞,同時將用戶引導到相應的關鍵詞搜索上。Solr內置了檢索建議功能,它在Solr裏叫作Suggest模塊.該模塊可選擇基於提示詞文本作檢索建議,還支持經過針對索引的某個字段創建索引詞庫作檢索建議。在諸多文檔中都推薦使用基於索引來作檢索建議,所以咱們目前的實現也是採起該方案。 如今咱們開始配置Suggest模塊,首先在solrconfig.xml文件中配置Suggest依賴的SpellChecker模塊,而後再配置Suggest模塊,因此這兩個都須要配置。
配置完成以後,咱們進行一下測試,重啓Solr後,訪問以下連接
使用SolrJ時也一樣加入參數就能夠
經過threshold參數來限制一些不經常使用的詞不出如今智能提示列表中,當這個值設置過大時,可能致使結果太少,須要引發注意。目前主要存在的問題是使用freq排序算法,返回的結果徹底基於索引中字符的出現次數,沒有兼顧用戶搜索詞語的頻率,所以沒法將一些熱門詞排在更靠前的位置。這塊可定製SuggestWordScoreComparator來實現,目前尚未着手作這件事情。 6.6分組統計我這裏實現分組統計的方法是使用了Solr的Facet組件, Facet組件是Solr默認集成的一個組件. 6.6.1 Facet簡介 Facet是solr的高級搜索功能之一,能夠給用戶提供更友好的搜索體驗.在搜索關鍵字的同時,可以按照Facet的字段進行分組並統計
6.6.2 Facet字段 1. 適宜被Facet的字段 通常表明了實體的某種公共屬性,如商品的分類,商品的製造廠家,書籍的出版商等等. 2. Facet字段的要求 Facet的字段必須被索引.通常來講該字段無需分詞,無需存儲. 無需分詞是由於該字段的值表明了一個總體概念,如電腦的品牌」聯想」表明了一個整 體概念,若是拆成」聯」,」想」兩個字都不具備實際意義.另外該字段的值無需進行大小 寫轉換等處理,保持其原貌便可. 無需存儲是由於通常而言用戶所關心的並非該字段的具體值,而是做爲對查詢結果進 行分組的一種手段,用戶通常會沿着這個分組進一步深刻搜索. 3. 特殊狀況 對於通常查詢而言,分詞和存儲都是必要的.好比CPU類型」Intel 酷睿2雙核 P7570」, 拆分紅」Intel」,」酷睿」,」P7570」這樣一些關鍵字並分別索引,可能提供更好的搜索 體驗.可是若是將CPU做爲Facet字段,最好不進行分詞.這樣就形成了矛盾,解決方法爲, 將CPU字段設置爲不分詞不存儲,而後創建另一個字段爲它的COPY,對這個COPY的 字段進行分詞和存儲.
6.6.2 Facet組件 Solr的默認requestHandler已經包含了Facet組件(solr.FacetComponent).若是自定義requestHandler或者對默認的requestHandler自定義組件列表,那麼須要將Facet加入到組件列表中去.
6.6.2 Facet查詢 進行Facet查詢須要在請求參數中加入facet=on或者facet=true只有這樣Facet組件才起做用. 1. Field Facet Facet字段經過在請求中加入facet.field參數加以聲明,若是須要對多個字段進行Facet查詢,那麼將該參數聲明屢次.例如: 返回結果:
各個Facet字段互不影響,且能夠針對每一個Facet字段設置查詢參數.如下介紹的參數既能夠應用於全部的Facet字段,也能夠應用於每一個單獨的Facet字段.應用於單獨的字段時經過
這種方式調用.好比facet.prefix參數應用於cpu字段,能夠採用以下形式
1.1 facet.prefix 表示Facet字段值的前綴.好比facet.field=cpu&facet.prefix=Intel,那麼對cpu字段進行Facet查詢,返回的cpu都是以Intel開頭的, AMD開頭的cpu型號將不會被統計在內. 1.2 facet.sort 表示Facet字段值以哪一種順序返回.可接受的值爲true(count)|false(index,lex). true(count)表示按照count值從大到小排列. false(index,lex)表示按照字段值的天然順序(字母,數字的順序)排列.默認狀況下爲true(count).當facet.limit值爲負數時,默認facet.sort= false(index,lex). 1.3 facet.limit 限制Facet字段返回的結果條數.默認值爲100.若是此值爲負數,表示不限制. 1.4 facet.offset 返回結果集的偏移量,默認爲0.它與facet.limit配合使用能夠達到分頁的效果. 1.5 facet.mincount 限制了Facet字段值的最小count,默認爲0.合理設置該參數能夠將用戶的關注點集中在少數比較熱門的領域. 1.6 facet.missing 默認爲」」,若是設置爲true或者on,那麼將統計那些該Facet字段值爲null的記錄. 1.7 facet.method 取值爲enum或fc,默認爲fc.該字段表示了兩種Facet的算法,與執行效率相關. enum適用於字段值比較少的狀況,好比字段類型爲布爾型,或者字段表示中國的全部省份.Solr會遍歷該字段的全部取值,並從filterCache裏爲每一個值分配一個filter(這裏要求solrconfig.xml裏對filterCache的設置足夠大).而後計算每一個filter與主查詢的交集. fc(表示Field Cache)適用於字段取值比較多,但在每一個文檔裏出現次數比較少的狀況.Solr會遍歷全部的文檔,在每一個文檔內搜索Cache內的值,若是找到就將Cache內該值的count加1. 1.8 facet.enum.cache.minDf 當facet.method=enum時,此參數其做用,minDf表示minimum document frequency.也就是文檔內出現某個關鍵字的最少次數.該參數默認值爲0.設置該參數能夠減小filterCache的內存消耗,但會增長總的查詢時間(計算交集的時間增長了).若是設置該值的話,官方文檔建議優先嚐試25-50內的值. 6.6.3 Date Facet 日期類型的字段在文檔中很常見,如商品上市時間,貨物出倉時間,書籍上架時間等等.某些狀況下須要針對這些字段進行Facet.不過期間字段的取值有無限性,用戶每每關心的不是某個時間點而是某個時間段內的查詢統計結果. Solr爲日期字段提供了更爲方便的查詢統計方式.固然,字段的類型必須是DateField(或其子類型). 須要注意的是,使用Date Facet時,字段名,起始時間,結束時間,時間間隔這4個參數都必須提供.與Field Facet相似,Date Facet也能夠對多個字段進行Facet.而且針對每一個字段均可以單獨設置參數. facet.date:該參數表示須要進行Date Facet的字段名,與facet.field同樣,該參數能夠被設置屢次,表示對多個字段進行Date Facet. facet.date.start:起始時間,時間的通常格式爲1995-12-31T23:59:59Z,另外可使用NOW\YEAR\ MONTH等等,具體格式能夠參考DateField的java doc. facet.date.end:結束時間. facet.date.gap:時間間隔.若是start爲2009-1-1,end爲2010-1-1.gap設置爲+1MONTH表示間隔1個月,那麼將會把這段時間劃分爲12個間隔段. 注意+由於是特殊字符因此應該用%2B代替. facet.date.hardend:取值能夠爲true|false,默認爲false.它表示gap迭代到end處採用何種處理.舉例說明start爲2009-1-1,end爲2009-12-25,gap爲+1MONTH, hardend爲false的話最後一個時間段爲2009-12-1至2010-1-1; hardend爲true的話最後一個時間段爲2009-12-1至2009-12-25. facet.date.other:取值範圍爲before|after|between|none|all,默認爲none.before會對start以前的值作統計.after會對end以後的值作統計.between會對start至end之間全部值作統計.若是hardend爲true的話,那麼該值就是各個時間段統計值的和.none表示該項禁用.all表示before,after,all都會統計. 舉例:
返回結果:
6.6.4 Facet Query Facet Query利用相似於filter query的語法提供了更爲靈活的Facet.經過facet.query參數,能夠對任意字段進行篩選. 例1:
返回結果:
例2:
返回結果:
例3:
返回結果:
6.6.5 key操做符 能夠用key操做符爲Facet字段取一個別名. 例:
返回結果:
6.6.6 tag操做符和ex操做符 當查詢使用filter query的時候,若是filter query的字段正好是Facet字段,那麼查詢結果每每被限制在某一個值內. 例:
返回結果:
能夠看到,屏幕尺寸(screenSize)爲14寸的產品共有107件,其它尺寸的產品的數目都是0,這是由於在filter裏已經限制了screenSize:14.這樣,查詢結果中,除了screenSize=14的這一項以外,其它項目沒有實際的意義.有些時候,用戶但願把結果限制在某一範圍內,又但願查看該範圍外的概況.好比上述狀況,既要把查詢結果限制在14寸屏的筆記本,又想查看一下其它屏幕尺寸的筆記本有多少產品.這個時候須要用到tag和ex操做符.tag就是把一個filter標記起來,ex(exclude)是在Facet的時候把標記過的filter排除在外. 例:
返回結果:
這樣其它屏幕尺寸的統計信息就有意義了. 6.6.7 SolrJ對Facet的支持
6.7自動聚類Solr 使用Carrot2完成了聚類功能,可以把檢索到的內容自動分類, Carrot2聚類示例:
要想Solr支持聚類功能,首選要把Solr發行包的中的dist/ solr-clustering-4.2.0.jar, 複製到\solr\contrib\analysis-extras\lib下.而後打開solrconfig.xml進行添加配置:
配好了聚類組件後,下面配置requestHandler:
有兩個參數要注意carrot.title, carrot.snippet是聚類的比較計算字段,這兩個參數必須是stored="true".carrot.title的權重要高於carrot.snippet,若是隻有一個作計算的字段carrot.snippet能夠去掉(是去掉不是值爲空).設完了用下面的URL就能夠查詢了 http://localhost:8983/skyCore/clustering?q=*%3A*&wt=xml&indent=true 6.8類似匹配在咱們使用網頁搜索時,會注意到每個結果都包含一個 「類似頁面」 連接,單擊該連接,就會發布另外一個搜索請求,查找出與起初結果相似的文檔。Solr 使用 MoreLikeThisComponent(MLT)和 MoreLikeThisHandler 實現了同樣的功能。如上所述,MLT 是與標準 SolrRequestHandler 集成在一塊兒的;MoreLikeThisHandler 與 MLT 結合在一塊兒,並添加了一些其餘選項,但它要求發佈一個單一的請求。我將着重講述 MLT,由於使用它的可能性更大一些。幸運的是,不須要任何設置就能夠查詢它,因此您如今就能夠開始查詢。 MLT 要求字段被儲存或使用檢索詞向量,檢索詞向量以一種以文檔爲中心的方式儲存信息。MLT 經過文檔的內容來計算文檔中關鍵詞語,而後使用原始查詢詞語和這些新詞語建立一個新的查詢。提交新查詢就會返回其餘查詢結果。全部這些均可以用檢索詞向量來完成:只需將 termVectors="true" 添加到 schema.xml 中的 <field> 聲明。 MoreLikeThisComponent 參數:
要想使用匹配類似首先在 solrconfig.xml 中配置 MoreLikeThisHandler
而後我就能夠請求 上面請求的意思查找 id 爲 6F398CCD-2DE0-D3B1-9DD6-D4E532FFC531 的 document ,而後返回與此 document 在 name 字段上類似的其餘 document。須要注意的是 mlt.fl 中的 field 的 termVector=true 纔有效果
使用SolrJ時也一樣加入參數就能夠
6.9拼音檢索拼音檢索中國人的專用檢索,例如:中文內容爲 中國 的輸入zhongguo、zg、zhonggu 全拼、簡拼、拼音的相鄰的一部份都應該能檢索出 中國 來。 想要實現拼音檢索第一個就是拼音轉換我這裏用的是pinyin4j進行拼音轉換。第二個就是N-Gram的題目,推敲到用戶可能輸入的既不是前綴也不是後綴,因此此處選擇的是N-Gram技巧,但不一樣於經常使用的N-Gram,我應用的從一邊開端的單向的N-Gram,Solr裏的實現叫EdgeNGramTokenFilter,可是分的分的太細了,不須要這麼複雜EdgeNGramTokenFilter,也就是說咱們用的N-Gram不一樣於傳統的N-Gram。 一樣的例子使用EdgeNGramTokenFilter從前日後取2-Gram的結果是zh, 通常是取min–max之間的全部gram,因此使用EdgeNGramTokenFilter取2-20的gram結果就是zh,zho, zhon, zhong, zhongg, zhonggu, zhongguo, 從這個例子也不難理解爲何我要選擇使用EdgeNGramTokenFilter而非通常意義上的N-Gram, 考慮到用戶可能輸入的不是前綴而是後綴,因此爲了照顧這些用戶,我選擇了從前日後和從後往前使用了兩次EdgeNGramTokenFilter,這樣不僅是前綴、後綴,二十任意的字串都考慮進去了,因此大幅度的提升了搜索體驗. 如今思路明確了咱們把它結合到Solr中,爲了方便使用如今寫了兩個Filter進行處理拼音分詞問題一個是拼音轉換Filter(PinyinTransformTokenFilter)一個是拼音N-Gram的Filter(PinyinNGramTokenFilter),這樣一來使用時就不用在添加索引前作攔音的轉換了。並且PinyinTransformTokenFilter還有個好處就是它只使用中文分詞器分過的詞,也就是說作轉換的詞都是有用的不重複的,不會對沒用的停詞類的作拼音轉換和重複拼音轉換,這樣大大的提升了拼音轉換速度。 想要Solr支持拼音檢索就要先把拼音分詞(PinyinAnalyzer)的jar複製到\solr\contrib\analysis-extras\lib下,而後在schema.xml中配置一個拼音字段類型:
minTermLenght:最小中文詞長度,意思是小於這個值的中文詞不會作拼音轉換。 minGram:最小拼音切分長度。 在這個拼音類型中咱們使用了smartcn的中言語分詞器,若是想使用其它的本身換掉就好了。如今咱們在原來索引中加入一個拼音字段,由於只作索引,咱們能夠這樣配置:
加完後咱們從新啓動Solr測試一下看看
因爲上面minTermLenght和minGram設置的值,如今出現了人沒有進行拼音轉換而且最小拼音切分是從1個開始的。 到這裏咱們的配置還有沒完成呢,還要加幾個copyFiled,這樣就不用單獨處理咱們新加的拼音字段了。方便呀~~~
到如今就可使用拼音檢索了。 我寫的拼音jar http://pan.baidu.com/share/link?shareid=2579170560&uk=4077294790 6.10 SolrCloudSolrCloud是基於Solr和Zookeeper的分佈式搜索方案,是正在開發中的Solr4.0的核心組件之一,它的主要思想是使用Zookeeper做爲集羣的配置信息中心。它有幾個特點功能,集中式的配置信息、自動容錯 、近實時搜索 、查詢時自動負載均衡。
基本能夠用上面這幅圖來概述,這是一個擁有4個Solr節點的集羣,索引分佈在兩個Shard裏面,每一個Shard包含兩個Solr節點,一個是Leader節點,一個是Replica節點,此外集羣中有一個負責維護集羣狀態信息的Overseer節點,它是一個總控制器。集羣的全部狀態信息都放在Zookeeper集羣中統一維護。從圖中還能夠看到,任何一個節點均可以接收索引更新的請求,而後再將這個請求轉發到文檔所應該屬於的那個Shard的Leader節點,Leader節點更新結束完成,最後將版本號和文檔轉發給同屬於一個Shard的replicas節點。這裏就很少說SolrCloud了,等研究明白後再單寫一個文檔。
附1:schema.xml
附2:solrconfig.xml
參考資料及文獻http://wiki.apache.org/solr/ 全部的配置在這裏都有說明 http://doc.carrot2.org/ 聚類相關設置在這裏有說明 轉自:http://www.cnblogs.com/DjangoBlog/p/3768027 |
如非特別註明,本站內容均爲領悟書生原創,轉載請務必註明做者和原始出處。
本文地址:http://www.656463.com/article/EZZnIv.htm
2014-12-16 23:18:12| 發佈: | 瀏覽: 2680
http://www.cnblogs.com/guozk/p/3498831.html
Solr調研總結
1. Solr 是什麼?Solr它是一種開放源碼的、基於 Lucene Java 的搜索服務器,易於加入到 Web 應用程序中。Solr 提供了層面搜索(就是統計)、命中醒目顯示而且支持多種輸出格式(包括XML/XSLT 和JSON等格式)。它易於安裝和配置,並且附帶了一個基於HTTP 的管理界面。可使用 Solr 的表現優異的基本搜索功能,也能夠對它進行擴展從而知足企業的須要。Solr的特性包括:
2. Lucene 是什麼?Lucene是一個基於Java的全文信息檢索工具包,它不是一個完整的搜索應用程序,而是爲你的應用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta(雅加達) 家族中的一個開源項目。也是目前最爲流行的基於Java開源全文檢索工具包。目前已經有不少應用程序的搜索功能是基於 Lucene ,好比Eclipse 幫助系統的搜索功能。Lucene可以爲文本類型的數據創建索引,因此你只要把你要索引的數據格式轉化的文本格式,Lucene 就能對你的文檔進行索引和搜索。 3. Solr vs LuceneSolr與Lucene 並非競爭對立關係,偏偏相反Solr 依存於Lucene,由於Solr底層的核心技術是使用Lucene 來實現的,Solr和Lucene的本質區別有如下三點:搜索服務器,企業級和管理。Lucene本質上是搜索庫,不是獨立的應用程序,而Solr是。Lucene專一於搜索底層的建設,而Solr專一於企業應用。Lucene不負責支撐搜索服務所必須的管理,而Solr負責。因此說,一句話歸納 Solr: Solr是Lucene面向企業搜索應用的擴展。 Solr與Lucene架構圖:
Solr使用Lucene而且擴展了它!
Solr和Lucene這兩個一樣的索引,查詢中國: solr用時:0.073(秒) Lucene用時:1.071(秒) 4.搭建並調試Solr4.1 安裝虛擬機Solr 必須運行在Java1.6 或更高版本的Java 虛擬機中,運行標準Solr 服務只須要安裝JRE 便可,但若是須要擴展功能或編譯源碼則須要下載JDK 來完成。能夠經過下面的地址下載所需JDK 或JRE :
安裝 步驟請參考相應的幫助文檔。 4.2下載Solr本文針對Solr4.2版本進行調研的,下文介紹內容均針對Solr4.2版本,如與Solr 最新版本有出入請以官方網站內容爲準。Solr官方網站下載地址:http://lucene.apache.org/solr/ 4.3下載並設置Apache AntSolr是使用Ant進行管理的源碼, Ant是一種基於Java的build工具。理論上來講,它有些相似於Maven 或者是 C中的make。下載後解壓出來後,進行環境變量設置。 ANT_HOME:E:\Work\apache-ant\1.9.1 (這裏爲你本身解壓縮的目錄) PATH:%ANT_HOME%\bin (這個設置是爲了方便在dos環境下操做) 查看是否安裝成功,在命令行窗口中輸入命令ant,若出現結果:
其它的先不用管它,咱們只要針對咱們使用的IDE進行build就好了,若是使用eclipse就在命令行輸入:ant eclipse.若是使用IntelliJ IDEA 就在命令行輸入:ant idea。這樣就能進行build了。 黑窗口裏提示這個。。。
失敗。。。爲何呢,最後我發現是由於下載的ant中少了一個jar就是這apache-ivy(下載地址:http://ant.apache.org/ivy/)這東東名子真怪 ivy是ant管理jar依賴關係的。當第一次bulid時ivy會自動把build中的缺乏的依賴進行下載。網速慢的第一次build要很久的。。。 下載一個jar就行把jar放到ant的lib下(E:\Work\apache-ant\1.9.1\lib)這樣再次運行ant 就會成功了。到如今才能夠進行Solr的代碼調試。 4.4配置並運行Solr代碼無論用什麼IDE首選都要設置Solr Home在IDE的JVM參數設置VM arguments寫入 -Dsolr.solr.home=solr/example/solr通常就好了.不行也可使用絕對路徑. solr使用StartSolrJetty文件做爲入口文件進行調試代碼,在這裏能夠設置服務器使用的端口和solr的webapps目錄.通常都不用設置,默認的就能夠進行調試.Solr Home也能可在代碼中設置同樣好用. System.setProperty("solr.solr.home", "E:\\Work\\solr-4.2.0-src-idea\\solr\\example\\solr"); 目前是使用自帶的一個example做爲solr配置的根目錄,若是你有其餘的solr配置目錄,設置之便可。點擊run便可,debug也是同樣能夠用了。沒有別的問題就應該能運行了.注意servlet 容器使用的端口,如查提示: FAILED SocketConnector@0.0.0.0:8983: java.net.BindException: Address already in use: JVM_Bind 就說明當前端口占用中.改一下就能夠了.若是沒有報錯啓動成功後就能夠在瀏覽器中輸入地址: http://localhost:8983/solr/ 就能夠看到以下界面
到這裏Solr就成功配置並運行了.要是想跟代碼調試在啓動時在這個方法裏點斷點就能夠Initializer的initialize()方法若是想從瀏覽器中找斷點調試就要到SolrDispatchFilter的doFilter方法中點斷點了. 注:IE9在兼容模式下有bug,必須設置爲非兼容模式。 5.Solr基礎由於 Solr 包裝並擴展了Lucene,因此它們使用不少相同的術語。更重要的是,Solr 建立的索引與 Lucene 搜索引擎庫徹底兼容。經過對 Solr 進行適當的配置,某些狀況下可能須要進行編碼,Solr 能夠閱讀和使用構建到其餘 Lucene 應用程序中的索引。在 Solr 和 Lucene 中,使用一個或多個 Document 來構建索引。Document 包括一個或多個 Field。Field 包括名稱、內容以及告訴 Solr 如何處理內容的元數據。 例如,Field 能夠包含字符串、數字、布爾值或者日期,也能夠包含你想添加的任何類型,只需用在solr的配置文件中進行相應的配置便可。Field 可使用大量的選項來描述,這些選項告訴 Solr 在索引和搜索期間如何處理內容。 如今,查看一下表 1 中列出的重要屬性的子集:
5.1模式配置Schema.xmlschema.xml這個配置文件能夠在你下載solr包的安裝解壓目錄的\solr\example\solr\collection1\conf中找到,它就是solr模式關聯的文件。打開這個配置文件,你會發現有詳細的註釋。模式組織主要分爲三個重要配置 5.1.1. types 部分 是一些常見的可重用定義,定義了 Solr(和 Lucene)如何處理 Field。也就是添加到索引中的xml文件屬性中的類型,如int、text、date等.
參數說明:
5.1.2. fileds 是你添加到索引文件中出現的屬性名稱,而聲明類型就須要用到上面的types
還有一個特殊的字段copyField,通常用於檢索時用的字段這樣就只對這一個字段進行索引分詞就好了copyField的dest字段若是有多個source必定要設置multiValued=true,不然會報錯的
字段屬性說明:
注意:_version_ 是一個特殊字段,不能刪除,是記錄當前索引版本號的. 5.1.3. 其餘配置 uniqueKey: 惟一鍵,這裏配置的是上面出現的fileds,通常是id、url等不重複的。在更新、刪除的時候能夠用到。 defaultSearchField:默認搜索屬性,如q=solr就是默認的搜索那個字段 solrQueryParser:查詢轉換模式,是而且仍是或者(AND/OR必須大寫) 5.2. solr配置solrconfig.xmlsolrconfig.xml這個配置文件能夠在你下載solr包的安裝解壓目錄的E:\Work\solr-4.2.0-src-idea\solr\example\solr\collection1\conf中找到,這個配置文件內容有點多,主要內容有:使用的lib配置,包含依賴的jar和Solr的一些插件;組件信息配置;索引配置和查詢配置,下面詳細說一下索引配置和查詢配置. 5.2.1索引indexConfig Solr 性能因素,來了解與各類更改相關的性能權衡。 表 1 歸納了可控制 Solr 索引處理的各類因素:
5.2.2 查詢配置query
5.3Solr加入中文分詞器中文分詞在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中.
5.3.1. 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定義的那一段,在下面多添加這一段就好啦
若是須要檢索某個字段,還須要在scheme.xml下面的field中,添加指定的字段,用text_ smartcn做爲type的名字,來完成中文分詞。如 text要實現中文檢索的話,就要作以下的配置:
5.3.2. IK 分詞器的安裝 首選要去下載IKAnalyzer的發行包.下載地址: 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了.
如今來驗證下是否添加成功,首先使用StartSolrJetty來啓動solr服務,啓動過程當中若是配置出錯,通常有兩個緣由:一是配置的分詞器jar找不到,也就是你沒有複製jar包到\solr\contrib\analysis-extras\lib目前下;二是分詞器版本不對致使的分詞器接口API不同出的錯,要是這個錯的話就在檢查分詞器的相關文檔,看一下支持的版本是否同樣. 若是在啓動過程當中沒有報錯的話說明配置成功了.咱們能夠進入到http://localhost:8983/solr地址進行測試一下剛加入的中文分詞器.在首頁的Core Selector中選擇你配置的Croe後點擊下面的Analysis,在Analyse Fieldname / FieldType裏選擇你剛纔設置的字段名稱或是分詞器類型,在Field Value(index)中輸入:中國人,點擊右面的分詞就好了.
6.Solr功能應用我這裏主要使用SolrJ進行介紹一下Solr的一些基本應用,使用SolrJ加上EmbeddedSolrServer(嵌入式服務器),方便進行代碼跟蹤調試.在功能上和其它服務器都是同樣的,它們都是繼承的SolrServer來提供服務API的. EmbeddedSolrServer優勢是不用起http協議,直接加載SolrCore進行操做,性能上應該是最快的,方便用於把Solr單結點服務嵌入到項目中使用.下面開始介紹Solr的功能的應用.EmbeddedSolrServer初始化:
6.1維護索引在通常系統中維護的都是增刪改,在Solr中的維護功能是增刪和優化功能,在Solr中的修改操做就是先刪掉再添加.在作索引維護以前,首先要作的是配置schema.xml主要是按上面章節中的說明設置好字段信息(名稱,類型,索引,存儲,分詞等信息),大概就像在數據庫中新建一個表同樣.設置好schema.xml就能夠進行索引相關操做了. 6.1.1增長索引 在增長索引以前先可構建好SolrInputDocument對象.主要操做就是給文檔添加字段和值.代碼以下:
構建好文檔後添加的上面初始化好的server裏就好了.
Solr在add文檔時.若是文檔不存在就直接添加,若是文檔存在就刪除後添加,這也就是修改功能了.判斷文檔是否存在的依據是定義好的uniqueKey字段. 6.1.2刪除索引 刪除索引能夠經過兩種方式操做,一種是經過文檔ID進行刪除,別一種是經過查詢到的結果進行刪除. 經過ID刪除方式代碼:
經過查詢刪除方式代碼:
6.1.2優化索引 優化Lucene 的索引文件以改進搜索性能。索引完成後執行一下優化一般比較好。若是更新比較頻繁,則應該在使用率較低的時候安排優化。一個索引無需優化也能夠正常地運行。優化是一個耗時較多的過程。
6.2文本檢索Solr在不修改任務配置的狀況下就可使用文本檢索功能,在web項目中應用能夠直接URL進行訪問Solr服務器例如 :
上面的意思就是檢索名爲collection1的SolrCore的全部內容用xml格式返回而且有縮進。 返回結果以下:
上面所看到的就是用xml格式返回的查詢結果,其中的doc就是一個文檔,在doc裏面的那個就是咱們開始在schema.xml中定義的字段. 若是使用SolrJ進行調用的話代碼以下:
返回結果在SolrDocumentList中在這個對象中遍歷取出值來:
6.2.1查詢參數
6.2.2查詢語法 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的。 4. 子表達式查詢(子查詢):可使用「()」構造子查詢。 示例:(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.五、make-believ~0.八、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年前前一天的這個時間 6.2.3函數查詢(Function Query) 函數查詢 能夠利用 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 2. 函數的格式(Function Query Syntax) 目前,function query 並不支持 a+b 這樣的形式,咱們得把它寫成一個方法形式,這就是 sum(a,b). 3. 使用函數查詢注意事項 1) 用於函數查詢的field必須是被索引的; 2) 字段不能夠是多值的(multi-value) 4. 能夠利用的函數 (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) 6.3高亮顯示咱們常用搜索引擎,好比在baidu 搜索 java ,會出現以下結果,結果中與關鍵字匹配的地方是紅色顯示與其餘內容區別開來。
solr 默認已經配置了highlight 組件(詳見 SOLR_HOME/conf/sorlconfig.xml)。一般我出只須要這樣請求http://localhost:8983/solr/ collection1 /select? q=%E4%B8%AD%E5%9B%BD&start=0&rows=1&fl=content+path+&wt=xml&indent=true&hl=true&hl.fl=content 能夠看到與比通常的請求多了兩個參數 "hl=true" 和 "hl.fl= content " 。 "hl=true" 是開啓高亮,"hl.fl= content " 是告訴solr 對 name 字段進行高亮(若是你想對多個字段進行高亮,能夠繼續添加字段,字段間用逗號隔開,如 "hl.fl=name,name2,name3")。 高亮內容與關鍵匹配的地方,默認將會被 "<em>" 和 "</em>" 包圍。還可使用hl.simple.pre" 和 "hl.simple.post"參數設置先後標籤. 查詢結果以下:
使用SolrJ方法基本同樣也是設置這些個參數,只不過是SolrJ封裝起來了,代碼以下:
6.4拼寫檢查首先配置 solrconfig.xml,文件可能已經有這兩個元素(若是沒有添加便可),須要根據咱們本身的系統環境作些適當的修改。
配置完成以後,咱們進行一下測試,重啓Solr後,訪問以下連接
使用SolrJ時也一樣加入參數就能夠
6.5檢索建議檢索建議目前是各大搜索的標配應用,主要做用是避免用戶輸入錯誤的搜索詞,同時將用戶引導到相應的關鍵詞搜索上。Solr內置了檢索建議功能,它在Solr裏叫作Suggest模塊.該模塊可選擇基於提示詞文本作檢索建議,還支持經過針對索引的某個字段創建索引詞庫作檢索建議。在諸多文檔中都推薦使用基於索引來作檢索建議,所以咱們目前的實現也是採起該方案。 如今咱們開始配置Suggest模塊,首先在solrconfig.xml文件中配置Suggest依賴的SpellChecker模塊,而後再配置Suggest模塊,因此這兩個都須要配置。
配置完成以後,咱們進行一下測試,重啓Solr後,訪問以下連接
使用SolrJ時也一樣加入參數就能夠
經過threshold參數來限制一些不經常使用的詞不出如今智能提示列表中,當這個值設置過大時,可能致使結果太少,須要引發注意。目前主要存在的問題是使用freq排序算法,返回的結果徹底基於索引中字符的出現次數,沒有兼顧用戶搜索詞語的頻率,所以沒法將一些熱門詞排在更靠前的位置。這塊可定製SuggestWordScoreComparator來實現,目前尚未着手作這件事情。 6.6分組統計我這裏實現分組統計的方法是使用了Solr的Facet組件, Facet組件是Solr默認集成的一個組件. 6.6.1 Facet簡介 Facet是solr的高級搜索功能之一,能夠給用戶提供更友好的搜索體驗.在搜索關鍵字的同時,可以按照Facet的字段進行分組並統計
6.6.2 Facet字段 1. 適宜被Facet的字段 通常表明了實體的某種公共屬性,如商品的分類,商品的製造廠家,書籍的出版商等等. 2. Facet字段的要求 Facet的字段必須被索引.通常來講該字段無需分詞,無需存儲. 無需分詞是由於該字段的值表明了一個總體概念,如電腦的品牌」聯想」表明了一個整 體概念,若是拆成」聯」,」想」兩個字都不具備實際意義.另外該字段的值無需進行大小 寫轉換等處理,保持其原貌便可. 無需存儲是由於通常而言用戶所關心的並非該字段的具體值,而是做爲對查詢結果進 行分組的一種手段,用戶通常會沿着這個分組進一步深刻搜索. 3. 特殊狀況 對於通常查詢而言,分詞和存儲都是必要的.好比CPU類型」Intel 酷睿2雙核 P7570」, 拆分紅」Intel」,」酷睿」,」P7570」這樣一些關鍵字並分別索引,可能提供更好的搜索 體驗.可是若是將CPU做爲Facet字段,最好不進行分詞.這樣就形成了矛盾,解決方法爲, 將CPU字段設置爲不分詞不存儲,而後創建另一個字段爲它的COPY,對這個COPY的 字段進行分詞和存儲.
6.6.2 Facet組件 Solr的默認requestHandler已經包含了Facet組件(solr.FacetComponent).若是自定義requestHandler或者對默認的requestHandler自定義組件列表,那麼須要將Facet加入到組件列表中去.
6.6.2 Facet查詢 進行Facet查詢須要在請求參數中加入facet=on或者facet=true只有這樣Facet組件才起做用. 1. Field Facet Facet字段經過在請求中加入facet.field參數加以聲明,若是須要對多個字段進行Facet查詢,那麼將該參數聲明屢次.例如: 返回結果:
各個Facet字段互不影響,且能夠針對每一個Facet字段設置查詢參數.如下介紹的參數既能夠應用於全部的Facet字段,也能夠應用於每一個單獨的Facet字段.應用於單獨的字段時經過
這種方式調用.好比facet.prefix參數應用於cpu字段,能夠採用以下形式
1.1 facet.prefix 表示Facet字段值的前綴.好比facet.field=cpu&facet.prefix=Intel,那麼對cpu字段進行Facet查詢,返回的cpu都是以Intel開頭的, AMD開頭的cpu型號將不會被統計在內. 1.2 facet.sort 表示Facet字段值以哪一種順序返回.可接受的值爲true(count)|false(index,lex). true(count)表示按照count值從大到小排列. false(index,lex)表示按照字段值的天然順序(字母,數字的順序)排列.默認狀況下爲true(count).當facet.limit值爲負數時,默認facet.sort= false(index,lex). 1.3 facet.limit 限制Facet字段返回的結果條數.默認值爲100.若是此值爲負數,表示不限制. 1.4 facet.offset 返回結果集的偏移量,默認爲0.它與facet.limit配合使用能夠達到分頁的效果. 1.5 facet.mincount 限制了Facet字段值的最小count,默認爲0.合理設置該參數能夠將用戶的關注點集中在少數比較熱門的領域. 1.6 facet.missing 默認爲」」,若是設置爲true或者on,那麼將統計那些該Facet字段值爲null的記錄. 1.7 facet.method 取值爲enum或fc,默認爲fc.該字段表示了兩種Facet的算法,與執行效率相關. enum適用於字段值比較少的狀況,好比字段類型爲布爾型,或者字段表示中國的全部省份.Solr會遍歷該字段的全部取值,並從filterCache裏爲每一個值分配一個filter(這裏要求solrconfig.xml裏對filterCache的設置足夠大).而後計算每一個filter與主查詢的交集. fc(表示Field Cache)適用於字段取值比較多,但在每一個文檔裏出現次數比較少的狀況.Solr會遍歷全部的文檔,在每一個文檔內搜索Cache內的值,若是找到就將Cache內該值的count加1. 1.8 facet.enum.cache.minDf 當facet.method=enum時,此參數其做用,minDf表示minimum document frequency.也就是文檔內出現某個關鍵字的最少次數.該參數默認值爲0.設置該參數能夠減小filterCache的內存消耗,但會增長總的查詢時間(計算交集的時間增長了).若是設置該值的話,官方文檔建議優先嚐試25-50內的值. 6.6.3 Date Facet 日期類型的字段在文檔中很常見,如商品上市時間,貨物出倉時間,書籍上架時間等等.某些狀況下須要針對這些字段進行Facet.不過期間字段的取值有無限性,用戶每每關心的不是某個時間點而是某個時間段內的查詢統計結果. Solr爲日期字段提供了更爲方便的查詢統計方式.固然,字段的類型必須是DateField(或其子類型). 須要注意的是,使用Date Facet時,字段名,起始時間,結束時間,時間間隔這4個參數都必須提供.與Field Facet相似,Date Facet也能夠對多個字段進行Facet.而且針對每一個字段均可以單獨設置參數. facet.date:該參數表示須要進行Date Facet的字段名,與facet.field同樣,該參數能夠被設置屢次,表示對多個字段進行Date Facet. facet.date.start:起始時間,時間的通常格式爲1995-12-31T23:59:59Z,另外可使用NOW\YEAR\ MONTH等等,具體格式能夠參考DateField的java doc. facet.date.end:結束時間. facet.date.gap:時間間隔.若是start爲2009-1-1,end爲2010-1-1.gap設置爲+1MONTH表示間隔1個月,那麼將會把這段時間劃分爲12個間隔段. 注意+由於是特殊字符因此應該用%2B代替. facet.date.hardend:取值能夠爲true|false,默認爲false.它表示gap迭代到end處採用何種處理.舉例說明start爲2009-1-1,end爲2009-12-25,gap爲+1MONTH, hardend爲false的話最後一個時間段爲2009-12-1至2010-1-1; hardend爲true的話最後一個時間段爲2009-12-1至2009-12-25. facet.date.other:取值範圍爲before|after|between|none|all,默認爲none.before會對start以前的值作統計.after會對end以後的值作統計.between會對start至end之間全部值作統計.若是hardend爲true的話,那麼該值就是各個時間段統計值的和.none表示該項禁用.all表示before,after,all都會統計. 舉例:
返回結果:
6.6.4 Facet Query Facet Query利用相似於filter query的語法提供了更爲靈活的Facet.經過facet.query參數,能夠對任意字段進行篩選. 例1:
返回結果:
例2:
返回結果:
例3:
返回結果:
6.6.5 key操做符 能夠用key操做符爲Facet字段取一個別名. 例:
返回結果:
6.6.6 tag操做符和ex操做符 當查詢使用filter query的時候,若是filter query的字段正好是Facet字段,那麼查詢結果每每被限制在某一個值內. 例:
返回結果:
能夠看到,屏幕尺寸(screenSize)爲14寸的產品共有107件,其它尺寸的產品的數目都是0,這是由於在filter裏已經限制了screenSize:14.這樣,查詢結果中,除了screenSize=14的這一項以外,其它項目沒有實際的意義.有些時候,用戶但願把結果限制在某一範圍內,又但願查看該範圍外的概況.好比上述狀況,既要把查詢結果限制在14寸屏的筆記本,又想查看一下其它屏幕尺寸的筆記本有多少產品.這個時候須要用到tag和ex操做符.tag就是把一個filter標記起來,ex(exclude)是在Facet的時候把標記過的filter排除在外. 例:
返回結果:
這樣其它屏幕尺寸的統計信息就有意義了. 6.6.7 SolrJ對Facet的支持
6.7自動聚類Solr 使用Carrot2完成了聚類功能,可以把檢索到的內容自動分類, Carrot2聚類示例:
要想Solr支持聚類功能,首選要把Solr發行包的中的dist/ solr-clustering-4.2.0.jar, 複製到\solr\contrib\analysis-extras\lib下.而後打開solrconfig.xml進行添加配置:
配好了聚類組件後,下面配置requestHandler:
有兩個參數要注意carrot.title, carrot.snippet是聚類的比較計算字段,這兩個參數必須是stored="true".carrot.title的權重要高於carrot.snippet,若是隻有一個作計算的字段carrot.snippet能夠去掉(是去掉不是值爲空).設完了用下面的URL就能夠查詢了 http://localhost:8983/skyCore/clustering?q=*%3A*&wt=xml&indent=true 6.8類似匹配在咱們使用網頁搜索時,會注意到每個結果都包含一個 「類似頁面」 連接,單擊該連接,就會發布另外一個搜索請求,查找出與起初結果相似的文檔。Solr 使用 MoreLikeThisComponent(MLT)和 MoreLikeThisHandler 實現了同樣的功能。如上所述,MLT 是與標準 SolrRequestHandler 集成在一塊兒的;MoreLikeThisHandler 與 MLT 結合在一塊兒,並添加了一些其餘選項,但它要求發佈一個單一的請求。我將着重講述 MLT,由於使用它的可能性更大一些。幸運的是,不須要任何設置就能夠查詢它,因此您如今就能夠開始查詢。 MLT 要求字段被儲存或使用檢索詞向量,檢索詞向量以一種以文檔爲中心的方式儲存信息。MLT 經過文檔的內容來計算文檔中關鍵詞語,而後使用原始查詢詞語和這些新詞語建立一個新的查詢。提交新查詢就會返回其餘查詢結果。全部這些均可以用檢索詞向量來完成:只需將 termVectors="true" 添加到 schema.xml 中的 <field> 聲明。 MoreLikeThisComponent 參數:
要想使用匹配類似首先在 solrconfig.xml 中配置 MoreLikeThisHandler
而後我就能夠請求 上面請求的意思查找 id 爲 6F398CCD-2DE0-D3B1-9DD6-D4E532FFC531 的 document ,而後返回與此 document 在 name 字段上類似的其餘 document。須要注意的是 mlt.fl 中的 field 的 termVector=true 纔有效果
使用SolrJ時也一樣加入參數就能夠
6.9拼音檢索拼音檢索中國人的專用檢索,例如:中文內容爲 中國 的輸入zhongguo、zg、zhonggu 全拼、簡拼、拼音的相鄰的一部份都應該能檢索出 中國 來。 想要實現拼音檢索第一個就是拼音轉換我這裏用的是pinyin4j進行拼音轉換。第二個就是N-Gram的題目,推敲到用戶可能輸入的既不是前綴也不是後綴,因此此處選擇的是N-Gram技巧,但不一樣於經常使用的N-Gram,我應用的從一邊開端的單向的N-Gram,Solr裏的實現叫EdgeNGramTokenFilter,可是分的分的太細了,不須要這麼複雜EdgeNGramTokenFilter,也就是說咱們用的N-Gram不一樣於傳統的N-Gram。 一樣的例子使用EdgeNGramTokenFilter從前日後取2-Gram的結果是zh, 通常是取min–max之間的全部gram,因此使用EdgeNGramTokenFilter取2-20的gram結果就是zh,zho, zhon, zhong, zhongg, zhonggu, zhongguo, 從這個例子也不難理解爲何我要選擇使用EdgeNGramTokenFilter而非通常意義上的N-Gram, 考慮到用戶可能輸入的不是前綴而是後綴,因此爲了照顧這些用戶,我選擇了從前日後和從後往前使用了兩次EdgeNGramTokenFilter,這樣不僅是前綴、後綴,二十任意的字串都考慮進去了,因此大幅度的提升了搜索體驗. 如今思路明確了咱們把它結合到Solr中,爲了方便使用如今寫了兩個Filter進行處理拼音分詞問題一個是拼音轉換Filter(PinyinTransformTokenFilter)一個是拼音N-Gram的Filter(PinyinNGramTokenFilter),這樣一來使用時就不用在添加索引前作攔音的轉換了。並且PinyinTransformTokenFilter還有個好處就是它只使用中文分詞器分過的詞,也就是說作轉換的詞都是有用的不重複的,不會對沒用的停詞類的作拼音轉換和重複拼音轉換,這樣大大的提升了拼音轉換速度。 想要Solr支持拼音檢索就要先把拼音分詞(PinyinAnalyzer)的jar複製到\solr\contrib\analysis-extras\lib下,而後在schema.xml中配置一個拼音字段類型:
minTermLenght:最小中文詞長度,意思是小於這個值的中文詞不會作拼音轉換。 minGram:最小拼音切分長度。 在這個拼音類型中咱們使用了smartcn的中言語分詞器,若是想使用其它的本身換掉就好了。如今咱們在原來索引中加入一個拼音字段,由於只作索引,咱們能夠這樣配置:
加完後咱們從新啓動Solr測試一下看看
因爲上面minTermLenght和minGram設置的值,如今出現了人沒有進行拼音轉換而且最小拼音切分是從1個開始的。 到這裏咱們的配置還有沒完成呢,還要加幾個copyFiled,這樣就不用單獨處理咱們新加的拼音字段了。方便呀~~~
到如今就可使用拼音檢索了。 我寫的拼音jar http://pan.baidu.com/share/link?shareid=2579170560&uk=4077294790 6.10 SolrCloudSolrCloud是基於Solr和Zookeeper的分佈式搜索方案,是正在開發中的Solr4.0的核心組件之一,它的主要思想是使用Zookeeper做爲集羣的配置信息中心。它有幾個特點功能,集中式的配置信息、自動容錯 、近實時搜索 、查詢時自動負載均衡。
基本能夠用上面這幅圖來概述,這是一個擁有4個Solr節點的集羣,索引分佈在兩個Shard裏面,每一個Shard包含兩個Solr節點,一個是Leader節點,一個是Replica節點,此外集羣中有一個負責維護集羣狀態信息的Overseer節點,它是一個總控制器。集羣的全部狀態信息都放在Zookeeper集羣中統一維護。從圖中還能夠看到,任何一個節點均可以接收索引更新的請求,而後再將這個請求轉發到文檔所應該屬於的那個Shard的Leader節點,Leader節點更新結束完成,最後將版本號和文檔轉發給同屬於一個Shard的replicas節點。這裏就很少說SolrCloud了,等研究明白後再單寫一個文檔。
附1:schema.xml
附2:solrconfig.xml
|