CONAN ZONE

          你越掙扎我就越興奮

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks

          一、字段配置(schema)

           

          schema.xml位于solr/conf/目錄下,類似于數(shù)據(jù)表配置文件,

          定義了加入索引的數(shù)據(jù)的數(shù)據(jù)類型,主要包括type、fields和其他的一些缺省設(shè)置。

           

          1、先來看下type節(jié)點(diǎn),這里面定義FieldType子節(jié)點(diǎn),包括name,class,positionIncrementGap等一些參數(shù)。

          • name:就是這個(gè)FieldType的名稱。
          • class:指向org.apache.solr.analysis包里面對(duì)應(yīng)的class名稱,用來定義這個(gè)類型的行為。
          1. < schema   name = "example"   version = "1.2" >   
          2.   < types >   
          3.     < fieldType   name = "string"   class = "solr.StrField"   sortMissingLast = "true"   omitNorms = "true" />   
          4.     < fieldType   name = "boolean"   class = "solr.BoolField"   sortMissingLast = "true"   omitNorms = "true" />   
          5.     < fieldtype   name = "binary"   class = "solr.BinaryField" />   
          6.     < fieldType   name = "int"   class = "solr.TrieIntField"   precisionStep = "0"   omitNorms = "true"    
          7.                                                                 positionIncrementGap = "0" />   
          8.     < fieldType   name = "float"   class = "solr.TrieFloatField"   precisionStep = "0"   omitNorms = "true"    
          9.                                                                 positionIncrementGap = "0" />   
          10.     < fieldType   name = "long"   class = "solr.TrieLongField"   precisionStep = "0"   omitNorms = "true"    
          11.                                                                 positionIncrementGap = "0" />   
          12.     < fieldType   name = "double"   class = "solr.TrieDoubleField"   precisionStep = "0"   omitNorms = "true"    
          13.                                                                 positionIncrementGap = "0" />   
          14.   ...  
          15.   </ types >   
          16.   ...  
          17. </ schema >   

           

          必要的時(shí)候fieldType還需要自己定義這個(gè)類型的數(shù)據(jù)在建立索引和進(jìn)行查詢的時(shí)候要使用的分析器analyzer,包括分詞和過濾,如下:

          1. < fieldType   name = "text_ws"   class = "solr.TextField"   positionIncrementGap = "100" >   
          2.   < analyzer >   
          3.     < tokenizer   class = "solr.WhitespaceTokenizerFactory" />   
          4.   </ analyzer >   
          5. </ fieldType >   
          6. < fieldType   name = "text"   class = "solr.TextField"   positionIncrementGap = "100" >   
          7.   < analyzer   type = "index" >   
          8.     <!--這個(gè)分詞包是空格分詞,在向索引庫添加text類型的索引時(shí),Solr會(huì)首先用空格進(jìn)行分詞  
          9.          然后把分詞結(jié)果依次使用指定的過濾器進(jìn)行過濾,最后剩下的結(jié)果,才會(huì)加入到索引庫中以備查詢。  
          10.       注意:Solr的analysis包并沒有帶支持中文的包,需要自己添加中文分詞器,google下。    
          11.      -->   
          12.     < tokenizer   class = "solr.WhitespaceTokenizerFactory" />   
          13.         <!-- in this example, we will only use synonyms at query time  
          14.         < filter   class = "solr.SynonymFilterFactory"   synonyms = "index_synonyms.txt"    
          15.                                                   ignoreCase = "true"   expand = "false" />   
          16.         -->   
          17.         <!-- Case insensitive stop word removal.  
          18.           add enablePositionIncrements = true  in both the index and query  
          19.           analyzers to leave a 'gap' for more accurate phrase queries.  
          20.         -->   
          21.       < filter   class = "solr.StopFilterFactory"   
          22.                 ignoreCase = "true"   
          23.                 words = "stopwords.txt"   
          24.                 enablePositionIncrements = "true"   
          25.                 />   
          26.       < filter   class = "solr.WordDelimiterFilterFactory"   generateWordParts = "1"    
          27.               generateNumberParts = "1"   catenateWords = "1"   catenateNumbers = "1"    
          28.               catenateAll = "0"   splitOnCaseChange = "1" />   
          29.       < filter   class = "solr.LowerCaseFilterFactory" />   
          30.       < filter   class = "solr.SnowballPorterFilterFactory"   language = "English"    
          31.                                                        protected = "protwords.txt" />   
          32.     </ analyzer >   
          33.     < analyzer   type = "query" >   
          34.       < tokenizer   class = "solr.WhitespaceTokenizerFactory" />   
          35.         < filter   class = "solr.SynonymFilterFactory"   synonyms = "synonyms.txt"   ignoreCase = "true"    
          36.                                                                           expand = "true" />   
          37.         < filter   class = "solr.StopFilterFactory"   
          38.                 ignoreCase = "true"   
          39.                 words = "stopwords.txt"   
          40.                 enablePositionIncrements = "true"   
          41.                 />   
          42.         < filter   class = "solr.WordDelimiterFilterFactory"   generateWordParts = "1"    
          43.                 generateNumberParts = "1"   catenateWords = "0"   catenateNumbers = "0"    
          44.                                         catenateAll = "0"   splitOnCaseChange = "1" />   
          45.         < filter   class = "solr.LowerCaseFilterFactory" />   
          46.         < filter   class = "solr.SnowballPorterFilterFactory"   language = "English"    
          47.                                                          protected = "protwords.txt" />   
          48.       </ analyzer >   
          49. </ fieldType >   

           

          2、再來看下fields節(jié)點(diǎn)內(nèi)定義具體的字段(類似數(shù)據(jù)庫的字段),含有以下屬性:

          • name:字段名
          • type:之前定義過的各種FieldType
          • indexed:是否被索引
          • stored:是否被存儲(chǔ)(如果不需要存儲(chǔ)相應(yīng)字段值,盡量設(shè)為false)
          • multiValued:是否有多個(gè)值(對(duì)可能存在多值的字段盡量設(shè)置為true,避免建索引時(shí)拋出錯(cuò)誤)
          1. < fields >   
          2.     < field   name = "id"   type = "integer"   indexed = "true"   stored = "true"   required = "true"   />   
          3.     < field   name = "name"   type = "text"   indexed = "true"   stored = "true"   />   
          4.     < field   name = "summary"   type = "text"   indexed = "true"   stored = "true"   />   
          5.     < field   name = "author"   type = "string"   indexed = "true"   stored = "true"   />   
          6.     < field   name = "date"   type = "date"   indexed = "false"   stored = "true"   />   
          7.     < field   name = "content"   type = "text"   indexed = "true"   stored = "false"   />   
          8.     < field   name = "keywords"   type = "keyword_text"   indexed = "true"   stored = "false"   multiValued = "true"   />   
          9.     <!--拷貝字段-->   
          10.     < field   name = "all"   type = "text"   indexed = "true"   stored = "false"   multiValued = "true" />   
          11. </ fields >   

           

          3、建議建立一個(gè)拷貝字段,將所有的 全文本 字段復(fù)制到一個(gè)字段中,以便進(jìn)行統(tǒng)一的檢索:

               以下是拷貝設(shè)置:

          1. < copyField   source = "name"   dest = "all" />   
          2. < copyField   source = "summary"   dest = "all" />   

           

          4、動(dòng)態(tài)字段,沒有具體名稱的字段,用dynamicField字段

          如:name為*_i,定義它的type為int,那么在使用這個(gè)字段的時(shí)候,任務(wù)以_i結(jié)果的字段都被認(rèn)為符合這個(gè)定義。如name_i, school_i

          1. < dynamicField   name = "*_i"    type = "int"      indexed = "true"    stored = "true" />   
          2. < dynamicField   name = "*_s"    type = "string"    indexed = "true"    stored = "true" />   
          3. < dynamicField   name = "*_l"    type = "long"     indexed = "true"    stored = "true" />   
          4. < dynamicField   name = "*_t"    type = "text"      indexed = "true"    stored = "true" />   
          5. < dynamicField   name = "*_b"    type = "boolean"   indexed = "true"    stored = "true" />   
          6. < dynamicField   name = "*_f"    type = "float"    indexed = "true"    stored = "true" />   
          7. < dynamicField   name = "*_d"    type = "double"   indexed = "true"    stored = "true" />   
          8. < dynamicField   name = "*_dt"   type = "date"      indexed = "true"    stored = "true" />   

           

           

           

           

          schema.xml文檔注釋中的信息:

           

           

           

          1、為了改進(jìn)性能,可以采取以下幾種措施:

          • 將所有只用于搜索的,而不需要作為結(jié)果的field(特別是一些比較大的field)的stored設(shè)置為false
          • 將不需要被用于搜索的,而只是作為結(jié)果返回的field的indexed設(shè)置為false
          • 刪除所有不必要的copyField聲明
          • 為了索引字段的最小化和搜索的效率,將所有的 text fields的index都設(shè)置成field,然后使用copyField將他們都復(fù)制到一個(gè)總的 text field上,然后對(duì)他進(jìn)行搜索。
          • 為了最大化搜索效率,使用java編寫的客戶端與solr交互(使用流通信)
          • 在服務(wù)器端運(yùn)行JVM(省去網(wǎng)絡(luò)通信),使用盡可能高的Log輸出等級(jí),減少日志量。

          2、< schema name =" example " version =" 1.2 " >

          • name:標(biāo)識(shí)這個(gè)schema的名字
          • version:現(xiàn)在版本是1.2

          3、filedType

           

          < fieldType name =" string " class =" solr.StrField " sortMissingLast =" true " omitNorms =" true " />

          • name:標(biāo)識(shí)而已。
          • class和其他屬性決定了這個(gè)fieldType的實(shí)際行為。(class以solr開始的,都是在org.appache.solr.analysis包下)

          可選的屬性:

          • sortMissingLast和sortMissingFirst兩個(gè)屬性是用在可以內(nèi)在使用String排序的類型上(包括:string,boolean,sint,slong,sfloat,sdouble,pdate)。
          • sortMissingLast="true",沒有該field的數(shù)據(jù)排在有該field的數(shù)據(jù)之后,而不管請(qǐng)求時(shí)的排序規(guī)則。
          • sortMissingFirst="true",跟上面倒過來唄。
          • 2個(gè)值默認(rèn)是設(shè)置成false

           

          StrField類型不被分析,而是被逐字地索引/存儲(chǔ)。

          StrField和TextField都有一個(gè)可選的屬性“compressThreshold”,保證壓縮到不小于一個(gè)大小(單位:char)

           

           

          < fieldType name =" text " class =" solr.TextField " positionIncrementGap =" 100 " >

           

          solr.TextField 允許用戶通過分析器來定制索引和查詢,分析器包括一個(gè)分詞器(tokenizer)和多個(gè)過濾器(filter)

           

          • positionIncrementGap:可選屬性,定義在同一個(gè)文檔中此類型數(shù)據(jù)的空白間隔,避免短語匹配錯(cuò)誤。

          name:    字段類型名 
          class:    java類名 
          indexed:    缺省true。 說明這個(gè)數(shù)據(jù)應(yīng)被搜索和排序,如果數(shù)據(jù)沒有indexed,則stored應(yīng)是true。 
          stored:    缺省true。說明這個(gè)字段被包含在搜索結(jié)果中是合適的。如果數(shù)據(jù)沒有stored,則indexed應(yīng)是true。 
          sortMissingLast:    指沒有該指定字段數(shù)據(jù)的document排在有該指定字段數(shù)據(jù)的document的后面 
          sortMissingFirst:    指沒有該指定字段數(shù)據(jù)的document排在有該指定字段數(shù)據(jù)的document的前面 
          omitNorms:    字段的長(zhǎng)度不影響得分和在索引時(shí)不做boost時(shí),設(shè)置它為true。一般文本字段不設(shè)置為true。 
          termVectors:    如果字段被用來做more like this 和highlight的特性時(shí)應(yīng)設(shè)置為true。 
          compressed:    字段是壓縮的。這可能導(dǎo)致索引和搜索變慢,但會(huì)減少存儲(chǔ)空間,只有StrField和TextField是可以壓縮,這通常適合字段的長(zhǎng)度超過200個(gè)字符。 
          multiValued:    字段多于一個(gè)值的時(shí)候,可設(shè)置為true。 
          positionIncrementGap:    和multiValued
          一起使用,設(shè)置多個(gè)值之間的虛擬空白的數(shù)量

           

          < tokenizer class =" solr.WhitespaceTokenizerFactory " />

          空格分詞,精確匹配。

           

           

          < filter class =" solr.WordDelimiterFilterFactory " generateWordParts =" 1 " generateNumberParts =" 1 " catenateWords =" 1 " catenateNumbers =" 1 " catenateAll =" 0 " splitOnCaseChange =" 1 " />

          在分詞和匹配時(shí),考慮 "-"連字符,字母數(shù)字的界限,非字母數(shù)字字符,這樣 "wifi"或"wi fi"都能匹配"Wi-Fi"。

           

          < filter class =" solr.SynonymFilterFactory " synonyms =" synonyms.txt " ignoreCase =" true " expand =" true " />

          同義詞 

           

          < filter class =" solr.StopFilterFactory " ignoreCase =" true " words =" stopwords.txt " enablePositionIncrements =" true " />

          在禁用字(stopword)刪除后,在短語間增加間隔

          stopword:即在建立索引過程中(建立索引和搜索)被忽略的詞,比如is this等常用詞。在conf/stopwords.txt維護(hù)。

           

           

           

          4、fields

           

          < field name =" id " type =" string " indexed =" true " stored =" true " required =" true " />

          • name:標(biāo)識(shí)而已。
          • type:先前定義的類型。
          • indexed:是否被用來建立索引(關(guān)系到搜索和排序)
          • stored:是否儲(chǔ)存
          • compressed:[false],是否使用gzip壓縮(只有TextField和StrField可以壓縮)
          • mutiValued:是否包含多個(gè)值
          • omitNorms:是否忽略掉Norm,可以節(jié)省內(nèi)存空間,只有全文本field和need an index-time boost的field需要norm。(具體沒看懂,注釋里有矛盾)
          • termVectors:[false],當(dāng)設(shè)置true,會(huì)存儲(chǔ) term vector。當(dāng)使用MoreLikeThis,用來作為相似詞的field應(yīng)該存儲(chǔ)起來。
          • termPositions:存儲(chǔ) term vector中的地址信息,會(huì)消耗存儲(chǔ)開銷。
          • termOffsets:存儲(chǔ) term vector 的偏移量,會(huì)消耗存儲(chǔ)開銷。
          • default:如果沒有屬性需要修改,就可以用這個(gè)標(biāo)識(shí)下。

           

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

          包羅萬象(有點(diǎn)夸張)的field,包含所有可搜索的text fields,通過copyField實(shí)現(xiàn)。

           

          < copyField source =" cat " dest =" text " />

            < copyField source =" name " dest =" text " />
            < copyField source =" manu " dest =" text " />
            < copyField source =" features " dest =" text " />
            < copyField source =" includes " dest =" text " />

          在添加索引時(shí),將所有被拷貝field(如cat)中的數(shù)據(jù)拷貝到text field中

          作用:

          • 將多個(gè)field的數(shù)據(jù)放在一起同時(shí)搜索,提供速度
          • 將一個(gè)field的數(shù)據(jù)拷貝到另一個(gè),可以用2種不同的方式來建立索引。

           

           

          < dynamicField name =" *_i " type =" int " indexed =" true " stored =" true " />

           

          如果一個(gè)field的名字沒有匹配到,那么就會(huì)用動(dòng)態(tài)field試圖匹配定義的各種模式。

          • "*"只能出現(xiàn)在模式的最前和最后
          • 較長(zhǎng)的模式會(huì)被先去做匹配
          • 如果2個(gè)模式同時(shí)匹配上,最先定義的優(yōu)先

           

          < dynamicField name =" * " type =" ignored " multiValued=" true " />

          如果通過上面的匹配都沒找到,可以定義這個(gè),然后定義個(gè)type,當(dāng)String處理。(一般不會(huì)發(fā)生)

          但若不定義,找不到匹配會(huì)報(bào)錯(cuò)。

           

           

          5、其他一些標(biāo)簽

           

          < uniqueKey > id </ uniqueKey >

          文檔的唯一標(biāo)識(shí), 必須填寫這個(gè)field(除非該field被標(biāo)記required="false"),否則solr建立索引報(bào)錯(cuò)。

          < defaultSearchField > text </ defaultSearchField >

          如果搜索參數(shù)中沒有指定具體的field,那么這是默認(rèn)的域。

          < solrQueryParser defaultOperator =" OR " />

          配置搜索參數(shù)短語間的邏輯,可以是"AND|OR"。

           

           

           

          二、solrconfig.xml

           

          1、索引配置

           

          mainIndex 標(biāo)記段定義了控制Solr索引處理的一些因素.

          • useCompoundFile:通過將很多 Lucene 內(nèi)部文件整合到單一一個(gè)文件來減少使用中的文件的數(shù)量。這可有助于減少 Solr 使用的文件句柄數(shù)目,代價(jià)是降低了性能。除非是應(yīng)用程序用完了文件句柄,否則 false 的默認(rèn)值應(yīng)該就已經(jīng)足夠。

          • useCompoundFile:通過將很多Lucene內(nèi)部文件整合到一個(gè)文件,來減少使用中的文件的數(shù)量。這可有助于減少Solr使用的文件句柄的數(shù)目,代價(jià)是降低了性能。除非是應(yīng)用程序用完了文件句柄,否則false的默認(rèn)值應(yīng)該就已經(jīng)足夠了。
          • mergeFacor:決定Lucene段被合并的頻率。較小的值(最小為2)使用的內(nèi)存較少但導(dǎo)致的索引時(shí)間也更慢。較大的值可使索引時(shí)間變快但會(huì)犧牲較多的內(nèi)存。(典型的時(shí)間與空間 的平衡配置)
          • maxBufferedDocs:在合并內(nèi)存中文檔和創(chuàng)建新段之前,定義所需索引的最小文檔數(shù)。段是用來存儲(chǔ)索引信息的Lucene文件。較大的值可使索引時(shí)間變快但會(huì)犧牲較多內(nèi)存。
          • maxMergeDocs:控制可由Solr合并的 Document 的最大數(shù)。較小的值(<10,000)最適合于具有大量更新的應(yīng)用程序。
          • maxFieldLength:對(duì)于給定的Document,控制可添加到Field的最大條目數(shù),進(jìn)而階段該文檔。如果文檔可能會(huì)很大,就需要增加這個(gè)數(shù)值。然后,若將這個(gè)值設(shè)置得過高會(huì)導(dǎo)致內(nèi)存不足錯(cuò)誤。
          • unlockOnStartup:告知Solr忽略在多線程環(huán)境中用來保護(hù)索引的鎖定機(jī)制。在某些情況下,索引可能會(huì)由于不正確的關(guān)機(jī)或其他錯(cuò)誤而一直處于鎖定,這就妨礙了添加和更新。將其設(shè)置為true可以禁用啟動(dòng)索引,進(jìn)而允許進(jìn)行添加和更新。(鎖機(jī)制)

           

           2、查詢處理配置

           

          query標(biāo)記段中以下一些與緩存無關(guān)的特性:

          • maxBooleanClauses:定義可組合在一起形成以個(gè)查詢的字句數(shù)量的上限。正常情況1024已經(jīng)足夠。如果應(yīng)用程序大量使用了通配符或范圍查詢,增加這個(gè)限制將能避免當(dāng)值超出時(shí),拋出TooMangClausesException。
          • enableLazyFieldLoading:如果應(yīng)用程序只會(huì)檢索Document上少數(shù)幾個(gè)Field,那么可以將這個(gè)屬性設(shè)置為 true。懶散加載的一個(gè)常見場(chǎng)景大都發(fā)生在應(yīng)用程序返回一些列搜索結(jié)果的時(shí)候,用戶常常會(huì)單擊其中的一個(gè)來查看存儲(chǔ)在此索引中的原始文檔。初始的現(xiàn)實(shí)常常只需要現(xiàn)實(shí)很短的一段信息。若是檢索大型的Document,除非必需,否則就應(yīng)該避免加載整個(gè)文檔。

           

          query部分負(fù)責(zé)定義與在Solr中發(fā)生的時(shí)間相關(guān)的幾個(gè)選項(xiàng):

           

           

          概念:Solr(實(shí)際上是Lucene)使用稱為Searcher的Java類來處理Query實(shí)例。Searcher將索引內(nèi)容相關(guān)的數(shù)據(jù)加載到內(nèi)存中。根據(jù)索引、CPU已經(jīng)可用內(nèi)存的大小,這個(gè)過程可能需要較長(zhǎng)的一段時(shí)間。要改進(jìn)這一設(shè)計(jì)和顯著提高性能,Solr引入了一張“溫暖”策略,即把這些新的Searcher聯(lián)機(jī)以便為現(xiàn)場(chǎng)用戶提供查詢服務(wù)之前,先對(duì)它們進(jìn)行“熱身”。

          • newSearcher和firstSearcher事件,可以使用這些事件來制定實(shí)例化新Searcher或第一個(gè)Searcher時(shí),應(yīng)該執(zhí)行哪些查詢。如果應(yīng)用程序期望請(qǐng)求某些特定的查詢,那么在創(chuàng)建新Searcher或第一個(gè)Searcher時(shí)就應(yīng)該反注釋這些部分并執(zhí)行適當(dāng)?shù)牟樵儭?/li>

           

          query中的智能緩存:

           

          • filterCache:通過存儲(chǔ)一個(gè)匹配給定查詢的文檔 id 的無序集,過濾器讓 Solr 能夠有效提高查詢的性能。緩存這些過濾器意味著對(duì)Solr的重復(fù)調(diào)用可以導(dǎo)致結(jié)果集的快速查找。更常見的場(chǎng)景是緩存一個(gè)過濾器,然后再發(fā)起后續(xù)的精煉查詢,這種查詢能使用過濾器來限制要搜索的文檔數(shù)。
          • queryResultCache:為查詢、排序條件和所請(qǐng)求文檔的數(shù)量緩存文檔 id 的有序集合。
          • documentCache:緩存Lucene Document,使用內(nèi)部Lucene文檔id(以便不與Solr唯一id相混淆)。由于Lucene的內(nèi)部Document id 可以因索引操作而更改,這種緩存不能自熱。
          • Named caches:命名緩存是用戶定義的緩存,可被 Solr定制插件 所使用。

          其中filterCache、queryResultCache、Named caches(如果實(shí)現(xiàn)了org.apache.solr.search.CacheRegenerator)可以自熱。

          每個(gè)緩存聲明都接受最多四個(gè)屬性:

          • class:是緩存實(shí)現(xiàn)的Java名
          • size:是最大的條目數(shù)
          • initialSize:是緩存的初始大小
          • autoWarmCount:是取自舊緩存以預(yù)熱新緩存的條目數(shù)。如果條目很多,就意味著緩存的hit會(huì)更多,只不過需要花更長(zhǎng)的預(yù)熱時(shí)間。

          對(duì)于所有緩存模式而言,在設(shè)置緩存參數(shù)時(shí),都有必要在內(nèi)存、cpu和磁盤訪問之間進(jìn)行均衡。統(tǒng)計(jì)信息管理頁(管理員界面的Statistics)對(duì)于分析緩存的 hit-to-miss 比例以及微調(diào)緩存大小的統(tǒng)計(jì)數(shù)據(jù)都非常有用。而且,并非所有應(yīng)用程序都會(huì)從緩存受益。實(shí)際上,一些應(yīng)用程序反而會(huì)由于需要將某個(gè)永遠(yuǎn)也用不到的條目存儲(chǔ)在緩存中這一額外步驟而受到影響。

          posted on 2012-05-30 14:18 CONAN 閱讀(17483) 評(píng)論(0)  編輯  收藏 所屬分類: Solr
          主站蜘蛛池模板: 霍邱县| 桃园市| 南汇区| 津市市| 屯昌县| 阳朔县| 克山县| 屯门区| 衡东县| 临泽县| 柘荣县| 阳江市| 玛沁县| 泰兴市| 会昌县| 诸城市| 屯昌县| 华蓥市| 永平县| 汶上县| 安丘市| 四平市| 平阳县| 新民市| 苗栗县| 平昌县| 即墨市| 满洲里市| 汉中市| 奉新县| 肥乡县| 柳州市| 屯留县| 资中县| 扎赉特旗| 岑巩县| 永嘉县| 赤壁市| 平果县| 陇南市| 新河县|