1、字段配置(schema) java
schema.xml位於solr/conf/目錄下,相似於數據表配置文件, 數據庫
定義了加入索引的數據的數據類型,主要包括type、fields和其餘的一些缺省設置。 apache
一、先來看下type節點,這裏面定義FieldType子節點,包括name,class,positionIncrementGap等一些參數。 緩存
- name:就是這個FieldType的名稱。
- class:指向org.apache.solr.analysis包裏面對應的class名稱,用來定義這個類型的行爲。
- < schema name = "example" version = "1.2" >
- < types >
- < fieldType name = "string" class = "solr.StrField" sortMissingLast = "true" omitNorms = "true" />
- < fieldType name = "boolean" class = "solr.BoolField" sortMissingLast = "true" omitNorms = "true" />
- < fieldtype name = "binary" class = "solr.BinaryField" />
- < fieldType name = "int" class = "solr.TrieIntField" precisionStep = "0" omitNorms = "true"
- positionIncrementGap = "0" />
- < fieldType name = "float" class = "solr.TrieFloatField" precisionStep = "0" omitNorms = "true"
- positionIncrementGap = "0" />
- < fieldType name = "long" class = "solr.TrieLongField" precisionStep = "0" omitNorms = "true"
- positionIncrementGap = "0" />
- < fieldType name = "double" class = "solr.TrieDoubleField" precisionStep = "0" omitNorms = "true"
- positionIncrementGap = "0" />
- ...
- </ types >
- ...
- </ schema >
必要的時候fieldType還須要本身定義這個類型的數據在創建索引和進行查詢的時候要使用的分析器analyzer,包括分詞和過濾,以下: 服務器
- < fieldType name = "text_ws" class = "solr.TextField" positionIncrementGap = "100" >
- < analyzer >
- < tokenizer class = "solr.WhitespaceTokenizerFactory" />
- </ analyzer >
- </ fieldType >
- < fieldType name = "text" class = "solr.TextField" positionIncrementGap = "100" >
- < analyzer type = "index" >
- <!--這個分詞包是空格分詞,在向索引庫添加text類型的索引時,Solr會首先用空格進行分詞
- 而後把分詞結果依次使用指定的過濾器進行過濾,最後剩下的結果,纔會加入到索引庫中以備查詢。
- 注意:Solr的analysis包並無帶支持中文的包,須要本身添加中文分詞器,google下。
- -->
- < tokenizer class = "solr.WhitespaceTokenizerFactory" />
- <!-- in this example, we will only use synonyms at query time
- < filter class = "solr.SynonymFilterFactory" synonyms = "index_synonyms.txt"
- ignoreCase = "true" expand = "false" />
- -->
- <!-- Case insensitive stop word removal.
- add enablePositionIncrements = true in both the index and query
- analyzers to leave a 'gap' for more accurate phrase queries.
- -->
- < filter class = "solr.StopFilterFactory"
- ignoreCase = "true"
- words = "stopwords.txt"
- enablePositionIncrements = "true"
- />
- < filter class = "solr.WordDelimiterFilterFactory" generateWordParts = "1"
- generateNumberParts = "1" catenateWords = "1" catenateNumbers = "1"
- catenateAll = "0" splitOnCaseChange = "1" />
- < filter class = "solr.LowerCaseFilterFactory" />
- < filter class = "solr.SnowballPorterFilterFactory" language = "English"
- protected = "protwords.txt" />
- </ analyzer >
- < analyzer type = "query" >
- < tokenizer class = "solr.WhitespaceTokenizerFactory" />
- < filter class = "solr.SynonymFilterFactory" synonyms = "synonyms.txt" ignoreCase = "true"
- expand = "true" />
- < filter class = "solr.StopFilterFactory"
- ignoreCase = "true"
- words = "stopwords.txt"
- enablePositionIncrements = "true"
- />
- < filter class = "solr.WordDelimiterFilterFactory" generateWordParts = "1"
- generateNumberParts = "1" catenateWords = "0" catenateNumbers = "0"
- catenateAll = "0" splitOnCaseChange = "1" />
- < filter class = "solr.LowerCaseFilterFactory" />
- < filter class = "solr.SnowballPorterFilterFactory" language = "English"
- protected = "protwords.txt" />
- </ analyzer >
- </ fieldType >
二、再來看下fields節點內定義具體的字段(相似數據庫的字段),含有如下屬性: 網絡
- name:字段名
- type:以前定義過的各類FieldType
- indexed:是否被索引
- stored:是否被存儲(若是不須要存儲相應字段值,儘可能設爲false)
- multiValued:是否有多個值(對可能存在多值的字段儘可能設置爲true,避免建索引時拋出錯誤)
- < fields >
- < field name = "id" type = "integer" indexed = "true" stored = "true" required = "true" />
- < field name = "name" type = "text" indexed = "true" stored = "true" />
- < field name = "summary" type = "text" indexed = "true" stored = "true" />
- < field name = "author" type = "string" indexed = "true" stored = "true" />
- < field name = "date" type = "date" indexed = "false" stored = "true" />
- < field name = "content" type = "text" indexed = "true" stored = "false" />
- < field name = "keywords" type = "keyword_text" indexed = "true" stored = "false" multiValued = "true" />
- <!--拷貝字段-->
- < field name = "all" type = "text" indexed = "true" stored = "false" multiValued = "true" />
- </ fields >
三、建議創建一個拷貝字段,將全部的 全文本 字段複製到一個字段中,以便進行統一的檢索: 多線程
如下是拷貝設置: app
- < copyField source = "name" dest = "all" />
- < copyField source = "summary" dest = "all" />
四、動態字段,沒有具體名稱的字段,用dynamicField字段 性能
如:name爲*_i,定義它的type爲int,那麼在使用這個字段的時候,任務以_i結果的字段都被認爲符合這個定義。如name_i, school_i ui
- < dynamicField name = "*_i" type = "int" indexed = "true" stored = "true" />
- < dynamicField name = "*_s" type = "string" indexed = "true" stored = "true" />
- < dynamicField name = "*_l" type = "long" indexed = "true" stored = "true" />
- < dynamicField name = "*_t" type = "text" indexed = "true" stored = "true" />
- < dynamicField name = "*_b" type = "boolean" indexed = "true" stored = "true" />
- < dynamicField name = "*_f" type = "float" indexed = "true" stored = "true" />
- < dynamicField name = "*_d" type = "double" indexed = "true" stored = "true" />
- < dynamicField name = "*_dt" type = "date" indexed = "true" stored = "true" />
schema.xml文檔註釋中的信息:
一、爲了改進性能,能夠採起如下幾種措施:
- 將全部只用於搜索的,而不須要做爲結果的field(特別是一些比較大的field)的stored設置爲false
- 將不須要被用於搜索的,而只是做爲結果返回的field的indexed設置爲false
- 刪除全部沒必要要的copyField聲明
- 爲了索引字段的最小化和搜索的效率,將全部的 text fields的index都設置成field,而後使用copyField將他們都複製到一個總的 text field上,而後對他進行搜索。
- 爲了最大化搜索效率,使用java編寫的客戶端與solr交互(使用流通訊)
- 在服務器端運行JVM(省去網絡通訊),使用盡量高的Log輸出等級,減小日誌量。
二、< schema name =" example " version =" 1.2 " >
- name:標識這個schema的名字
- version:如今版本是1.2
三、filedType
< fieldType name =" string " class =" solr.StrField " sortMissingLast =" true " omitNorms =" true " />
- name:標識而已。
- class和其餘屬性決定了這個fieldType的實際行爲。(class以solr開始的,都是在org.appache.solr.analysis包下)
可選的屬性:
- sortMissingLast和sortMissingFirst兩個屬性是用在能夠內在使用String排序的類型上(包括:string,boolean,sint,slong,sfloat,sdouble,pdate)。
- sortMissingLast="true",沒有該field的數據排在有該field的數據以後,而無論請求時的排序規則。
- sortMissingFirst="true",跟上面倒過來唄。
- 2個值默認是設置成false
StrField類型不被分析,而是被逐字地索引/存儲。
StrField和TextField都有一個可選的屬性「compressThreshold」,保證壓縮到不小於一個大小(單位:char)
< fieldType name =" text " class =" solr.TextField " positionIncrementGap =" 100 " >
solr.TextField 容許用戶經過分析器來定製索引和查詢,分析器包括一個分詞器(tokenizer)和多個過濾器(filter)
- positionIncrementGap:可選屬性,定義在同一個文檔中此類型數據的空白間隔,避免短語匹配錯誤。
name: 字段類型名
class: java類名
indexed: 缺省true。 說明這個數據應被搜索和排序,若是數據沒有indexed,則stored應是true。
stored: 缺省true。說明這個字段被包含在搜索結果中是合適的。若是數據沒有stored,則indexed應是true。
sortMissingLast: 指沒有該指定字段數據的document排在有該指定字段數據的document的後面
sortMissingFirst: 指沒有該指定字段數據的document排在有該指定字段數據的document的前面
omitNorms: 字段的長度不影響得分和在索引時不作boost時,設置它爲true。通常文本字段不設置爲true。
termVectors: 若是字段被用來作more like this 和highlight的特性時應設置爲true。
compressed: 字段是壓縮的。這可能致使索引和搜索變慢,但會減小存儲空間,只有StrField和TextField是能夠壓縮,這一般適合字段的長度超過200個字符。
multiValued: 字段多於一個值的時候,可設置爲true。
positionIncrementGap: 和multiValued
一塊兒使用,設置多個值之間的虛擬空白的數量
< tokenizer class =" solr.WhitespaceTokenizerFactory " />
空格分詞,精確匹配。
< filter class =" solr.WordDelimiterFilterFactory " generateWordParts =" 1 " generateNumberParts =" 1 " catenateWords =" 1 " catenateNumbers =" 1 " catenateAll =" 0 " splitOnCaseChange =" 1 " />
在分詞和匹配時,考慮 "-"連字符,字母數字的界限,非字母數字字符,這樣 "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維護。
四、fields
< field name =" id " type =" string " indexed =" true " stored =" true " required =" true " />
- name:標識而已。
- type:先前定義的類型。
- indexed:是否被用來創建索引(關係到搜索和排序)
- stored:是否儲存
- compressed:[false],是否使用gzip壓縮(只有TextField和StrField能夠壓縮)
- mutiValued:是否包含多個值
- omitNorms:是否忽略掉Norm,能夠節省內存空間,只有全文本field和need an index-time boost的field須要norm。(具體沒看懂,註釋裏有矛盾)
- termVectors:[false],當設置true,會存儲 term vector。當使用MoreLikeThis,用來做爲類似詞的field應該存儲起來。
- termPositions:存儲 term vector中的地址信息,會消耗存儲開銷。
- termOffsets:存儲 term vector 的偏移量,會消耗存儲開銷。
- default:若是沒有屬性須要修改,就能夠用這個標識下。
< field name =" text " type =" text " indexed =" true " stored =" false " multiValued =" true " />
一應俱全(有點誇張)的field,包含全部可搜索的text fields,經過copyField實現。
< 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
" />
在添加索引時,將全部被拷貝field(如cat)中的數據拷貝到text field中
做用:
- 將多個field的數據放在一塊兒同時搜索,提供速度
- 將一個field的數據拷貝到另外一個,能夠用2種不一樣的方式來創建索引。
< dynamicField name =" *_i " type =" int " indexed =" true " stored =" true " />
若是一個field的名字沒有匹配到,那麼就會用動態field試圖匹配定義的各類模式。
- "*"只能出如今模式的最前和最後
- 較長的模式會被先去作匹配
- 若是2個模式同時匹配上,最早定義的優先
< dynamicField name =" * " type =" ignored " multiValued=" true " />
若是經過上面的匹配都沒找到,能夠定義這個,而後定義個type,當String處理。(通常不會發生)
但若不定義,找不到匹配會報錯。
五、其餘一些標籤
< uniqueKey > id </ uniqueKey >
文檔的惟一標識, 必須填寫這個field(除非該field被標記required="false"),不然solr創建索引報錯。
< defaultSearchField > text </ defaultSearchField >
若是搜索參數中沒有指定具體的field,那麼這是默認的域。
< solrQueryParser defaultOperator =" OR " />
配置搜索參數短語間的邏輯,能夠是"AND|OR"。
2、solrconfig.xml
一、索引配置
mainIndex 標記段定義了控制Solr索引處理的一些因素.
二、查詢處理配置
query標記段中如下一些與緩存無關的特性:
- maxBooleanClauses:定義可組合在一塊兒造成以個查詢的字句數量的上限。正常狀況1024已經足夠。若是應用程序大量使用了通配符或範圍查詢,增長這個限制將能避免當值超出時,拋出TooMangClausesException。
- enableLazyFieldLoading:若是應用程序只會檢索Document上少數幾個Field,那麼能夠將這個屬性設置爲 true。懶散加載的一個常見場景大都發生在應用程序返回一些列搜索結果的時候,用戶經常會單擊其中的一個來查看存儲在此索引中的原始文檔。初始的現實經常只須要現實很短的一段信息。如果檢索大型的Document,除非必需,不然就應該避免加載整個文檔。
query部分負責定義與在Solr中發生的時間相關的幾個選項:
概念:Solr(其實是Lucene)使用稱爲Searcher的Java類來處理Query實例。Searcher將索引內容相關的數據加載到內存中。根據索引、CPU已經可用內存的大小,這個過程可能須要較長的一段時間。要改進這一設計和顯著提升性能,Solr引入了一張「溫暖」策略,即把這些新的Searcher聯機以便爲現場用戶提供查詢服務以前,先對它們進行「熱身」。
- newSearcher和firstSearcher事件,可使用這些事件來制定實例化新Searcher或第一個Searcher時,應該執行哪些查詢。若是應用程序指望請求某些特定的查詢,那麼在建立新Searcher或第一個Searcher時就應該反註釋這些部分並執行適當的查詢。
query中的智能緩存:
- filterCache:經過存儲一個匹配給定查詢的文檔 id 的無序集,過濾器讓 Solr 可以有效提升查詢的性能。緩存這些過濾器意味着對Solr的重複調用能夠致使結果集的快速查找。更常見的場景是緩存一個過濾器,而後再發起後續的精煉查詢,這種查詢能使用過濾器來限制要搜索的文檔數。
- queryResultCache:爲查詢、排序條件和所請求文檔的數量緩存文檔 id 的有序集合。
- documentCache:緩存Lucene Document,使用內部Lucene文檔id(以便不與Solr惟一id相混淆)。因爲Lucene的內部Document id 能夠因索引操做而更改,這種緩存不能自熱。
- Named caches:命名緩存是用戶定義的緩存,可被 Solr定製插件 所使用。
其中filterCache、queryResultCache、Named caches(若是實現了org.apache.solr.search.CacheRegenerator)能夠自熱。
每一個緩存聲明都接受最多四個屬性:
- class:是緩存實現的Java名
- size:是最大的條目數
- initialSize:是緩存的初始大小
- autoWarmCount:是取自舊緩存以預熱新緩存的條目數。若是條目不少,就意味着緩存的hit會更多,只不過須要花更長的預熱時間。
對於全部緩存模式而言,在設置緩存參數時,都有必要在內存、cpu和磁盤訪問之間進行均衡。統計信息管理頁(管理員界面的Statistics)對於分析緩存的 hit-to-miss 比例以及微調緩存大小的統計數據都很是有用。並且,並不是全部應用程序都會從緩存受益。實際上,一些應用程序反而會因爲須要將某個永遠也用不到的條目存儲在緩存中這一額外步驟而受到影響。