目錄html
Solr將數據以結構化的形式存儲到文件系統中, 在存儲的過程當中對數據創建索引 —— 經過模式文件schema.xml文件來定義這個結構.apache
schema.xml
文件位於Solr安裝包的example/solr/collection1/conf/
目錄下, 主要用於配置Solr的域(Field)以及域的類型(FieldType).服務器
說明事項:併發
① Solr中Field相關內容要先配置再使用;dom
② schema.xml文件的名稱不能夠更改;性能
③ 在使用中也應該位於SolrHome/conf/
下 或者位於 Solr Web 應用的類加載器能夠加載到的位置.優化
這裏演示的
schema.xml
文件是Solr 4.10.4版本中的模式文件.ui
文件示例:this
<?xml version="1.0" encoding="UTF-8" ?> <schema name="user" version="1.5"> <field name="_version_" type="long" indexed="true" stored="true"/> <field name="_root_" type="string" indexed="true" stored="false"/> <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /> <field name="name" type="text_general" indexed="true" stored="true"/> <uniqueKey>id</uniqueKey> <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="string" class="solr.StrField" sortMissingLast="true" /> <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory"/> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory"/> </analyzer> </fieldType> </schema>
(1) 根元素是schema, name屬性值用來展現, 能夠任意配置, version是Solr模式語法和語義的版本號, Solr 4.10版本中使用1.5版本.編碼
1.0版本: multiValued屬性不存在, 全部字段本質上都是多值的;
1.1版本: 引入了multiValued屬性, 默認爲false;
1.2版本: 引入了omitTermFreqAndPositions屬性, 默認爲true, 文本字段除外;
1.3版本: 刪除了可選的字段壓縮功能;
1.4版本: autoGeneratePhraseQueries屬性, 用於在單個字符串生成多個標記時驅動QueryParser行爲. 1.4及以上的版本默認關閉;
1.5版本: 對於原始字段類型(如int, float, boolean, string...), omitNorms默認爲true.
(2)根元素下主要有field和fieldType兩個標籤, 分別用來定義域和域的類型.
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
field
相似於MySQL中數據表的字段, 屬性包括name, type(就是以前定義過的fieldType
)等等, 具體屬性說明以下:
(1)必需屬性:
①
name
: 域的名稱, 以字母或下劃線開頭, 不能由數字開頭;
②type
: 下面將定義的fieldType域的類型;
③indexed
: 若是此字段須要被檢索和排序, 就設置爲true;
④stored
: 若是這個字段在查詢的時候須要顯示出來, 就要設置爲true, 表示存儲它的原始值, 若是在檢索的時候不須要顯示原始值, 就儘可能設置爲false, 尤爲是值比較大的字段;
⑤required
: 代表該字段是必填字段, 相似於MySQL中的not null. 若設置爲true, 在建立索引時, 就必須包含該字段的值, 如過不存在, 就會拋出錯誤;
⑥multiValued
: 是否有多個值(在Solr中容許一個域保存多個值, 相似於MySQL中一個用戶能夠存儲多個好友, 一件商品有多個細節圖片).
原配置文件中的英文說明:
Although it would make indexing slightly slower and the index bigger, it would also make the index faster to load, more memory-efficient and more NRT-friendly.
大概意思是: 雖然它會使索引略微變慢、索引文件變得更大, 但它卻能使得索引更快被加載, 內存使用效率更高, 而且更友好的NRT(近實時搜索).
(2)可選屬性:
①
docValues
: 是否爲當前field添加一個名爲docValues的field --- 這對facet查詢、group分組、排序、function查詢有好處.a) 不足: 會使得索引過程略慢, 且索引文件更大;
b) 優勢: 能加快索引數據的加載, 對NRT(近實時搜索)也更加友好, 並且更節省內存;
c) 限制: 目前docValues只支持strField、UUIDField、Trie*Field; 要求字段的值是單值, 而且此field的值必須存在或具備默認值.
②
compressed
: 是否使用gzip壓縮(只有TextField和StrField能夠壓縮), 默認爲false;③
omitNorms
(專業屬性): 是否忽略掉Norm, 若是設置爲true, 將忽略與此字段相關聯的規範 (這將禁用字段的長度規範化和檢索時文檔權重分的提高, 並節省一些內存空間). 只有全文本的field和須要檢索時提高權重的field須要norm; 只有全文本類型的字段, 或者須要在檢索時對當前字段的權重進行設置時, 才須要相關規範, 此時須要將其設置爲false. 默認狀況下, 原始(未分析)類型的規範將被忽略.④
termVectors
: 默認false, 爲true時會存儲當前字段的term vector(術語向量), 使用MoreLikeThis時, 用來做爲類似性匹配的field的stored應該設置爲true, 以提升性能;⑤
termPositions
: 使用term vector存儲位置信息, 這會增大存儲成本;⑥
termOffsets
: 使用term vector存儲偏移量信息, 這會增大存儲成本;⑦
default
: 設置當前字段的默認值, 若是在添加文檔時沒有爲該字段指定值, 將使用此默認值.
(3)注意事項:
①
name="_version_"
的字段必須添加, 用來記錄Solr中文檔的版本. 若是刪除此字段, 則必須禁用solrconfig.xml
文件中的更新日誌, 不然Solr將沒法啓動. SolrCloud須要_version_
和更新日誌.②
name="_root_"
的字段用來指向嵌套文檔塊的根文檔, 有嵌套文檔時就必需存在此字段, 不然嵌套文檔可能會被刪除.③ 幾乎全部的Solr文檔中都存在
<uniqueKey>id</uniqueKey>
—— 主鍵爲id, 若是沒有充分的理由, 請不要刪除id字段. ⇒ 固然能夠根據實際狀況配置符合自身業務的主鍵.
fieldType供Solr內部使用, 不支持自定義域類型. 原始FieldType定義示例:
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory" /> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /> <!-- in this example, we will only use synonyms at query time <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/> --> <filter class="solr.LowerCaseFilterFactory" /> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory" /> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /> <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" /> <filter class="solr.LowerCaseFilterFactory" /> </analyzer> </fieldType>
(1)必需屬性:
①
name
: 域類型的名稱, 是field中的type;
②class
: 域類型對應的Solr的標準Java類, 以"Solr"開頭的class是org.apache.solr.analysis
包中的Java類;
③ analyzer: 定義索引和搜索使用的分詞器, **是核心配置 --- 使用的分析器不一樣, 索引和檢索也將不一樣**; ④
type: index(索引流程)和query(檢索流程); ⑤
tokenizer: 指定具體使用的分詞器; ⑥
filter`: 指定使用的過濾器;
(2)可選屬性:
①
positionIncrementGap
: 當multiValued="true"
時使用, 定義在同一個文檔中此類型數據的空白間隔, 即設置多個值之間的虛擬空白的數量, 避免短語匹配錯誤.②
autoGeneratePhraseQueries
: 有點相似找近義詞或者自動糾錯, 例如能夠將 "wi fi" 自動轉爲 "wifi" 或 "wi-fi", 若是不設置這個屬性則須要在查詢時強制加上引號, 如 'wi fi';③
sortMissingLast
/sortMissingFirst
: 對查詢結果進行排序的過程當中, 若是發現這個字段的值不存在, 就排在前面/後面, 忽略排序的條件. 使用方式以下:a) 默認值均爲false, 將使用Lucene內部的排序規則: 將沒有該字段的文檔放在升序中, 最後放在降序結果中. ;
b)
sortMissingLast="true"
, 對該字段進行排序時, 沒有該字段的文檔將排在有該字段的文檔的後面, 忽略請求時的排序規則(asc或desc);c)
sortMissingFirst="true"
, 與sortMissingLast
做用相反.
(3)常見域類型(class):
① solr.StrField
:
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
此類型不會被分詞, 而是被逐字索引/存儲. 它支持docValues域, 若是使用此fieldType的field添加了docValues字段, 則要求該field只能是單值域且該域必須存在或者該域有默認值.
② solr.BoolField
:
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
boolean域, 對應true/false.
③ solr.Trie*Field
: 默認的數字域類型:
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>
這些字段支持docValues, 但它們要求field爲單值, 而且要麼是必需的, 要麼具備默認值.
④ solr.Trie*Field
: 更快的範圍查詢的數字域類型:
若是須要更快的範圍查詢, 請考慮 tint / tfloat / tlong / tdouble
類型:
<fieldType name="tint" class="solr.TrieIntField" precisionStep="8" positionIncrementGap="0"/> <fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" positionIncrementGap="0"/> <fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" positionIncrementGap="0"/> <fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" positionIncrementGap="0"/>
此類型 以多種精度級別對每一個值建立不一樣的索引 , 用來加速範圍兩端間距較大時的範圍查詢.
precisionStep
: 通常用於數字範圍查詢, 其值越小(以位爲單位), 索引時該域的值分出的token個數越多 ⇒ 索引體積會稍大(slightly larger index size) ⇒ 但這能加快數字範圍檢索的響應速度.
precisionStep="0"
將禁用不一樣精度級別的索引.
positionIncrementGap
: 若是當前域是多值域時, 多個值之間的間距. 該屬性在單值域上無心義.
⑤ solr.TrieDateField
: 日期域類型:
<fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
日期字段只支持格式爲1995-12-31T23:59:59Z的日期, 最後的 Z
表示UTC時間, 而且必須是UTC時間.
其中, 只有秒數能夠選用小數: 1995-12-31T23:59:59.999Z, 其餘部分都是必需且格式不能改變的.
日期表達式也可用於表示相對於"NOW"(當前時刻)的時間, 如:
NOW/HOUR
⇒ 回到當前小時的開始時間;
NOW-1DAY
⇒ 剛好在前一天;
NOW/DAY+6MONTHS+3DAYS
⇒ 從當天開始, 未來6個月零3天的時刻.
注意: 對於更快的範圍的查詢和日期分面的需求, 請考慮使用tdate類型.
<fieldType name="tdate" class="solr.TrieDateField" precisionStep="6" positionIncrementGap="0"/>
⑥ solr.BinaryField
:
<fieldtype name="binary" class="solr.BinaryField"/>
通過Base64編碼的字符串域類型, 就是說須要把數據進行Base64編碼, 而後再發送/檢索.
⑦ solr.RandomSortField
:
<fieldType name="random" class="solr.RandomSortField" indexed="true" />
隨機排序域類型, 不用於存儲或搜索任何數據, 能夠在模式中聲明此類型的字段, 以實現文檔的僞隨機排序.
⇒ 根據字段名稱和索引的版本生成排序. 只要索引的版本
_version_
不變, 而且重用相同的字段名稱, 文檔的順序就會一致.
⇒ 若是須要不一樣的僞隨機文檔排序, 對於相同版本的索引, 請使用dynamicField並更改請求中的字段名稱.
⑧ solr.TextField
:
使用最多的一種域類型, 須要分詞, 通常須要用戶配置分析器來定製索引和查詢, 分析器包括一個分詞器(tokenizer)和多個過濾器(filter). 示例:
<!-- 空格分詞器, 精確匹配: 在向索引庫添加text類型的索引時, Solr會首先用空格進行分詞, 而後把分詞結果依次使用指定的過濾器進行過濾, 最後剩下的結果纔會加入到索引庫中以備查詢. 注意: Solr的analysis包並無支持中文的包, 須要本身添加中文分詞器. --> <fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="solr.WhitespaceTokenizerFactory" /> </analyzer> </fieldType>
(4)常見的過濾器(filter):
① 分隔符過濾器:
<!-- 在分詞和匹配時, 考慮 "-"連字符, 字母數字的界限, 非字母數字字符, 這樣"wifi"或"wi fi"都能匹配"Wi-Fi". --> <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1" />
② 同義詞過濾器:
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
③ 停詞(禁用詞)過濾器:
<!-- 在禁用字(stopword)刪除後, 在短語間增長間隔stopword: 即在創建索引過程當中(創建索引和搜索)被忽略的詞, 好比is this等經常使用詞. 在conf/stopwords.txt文件中設置維護. --> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
Solr容許將多個域的值, 複製給一個域, 目的是方便搜索.
好比: 搜索含有"Solr"的文檔, 須要把標題、摘要信息、正文中含有"Solr"的文檔都查詢出來, 有了copyField
域, 就只須要搜索copyField
域, 而不須要寫全標題、摘要信息、正文三個域的值.
在建立索引的時候, Solr會將源域的內容, 複製給目標域.
<copyField source="cat" dest="text"/>
(1)屬性說明:
①
source
: 源域的名稱;
②dest
: 目標域的名稱, 搜索時指定目標域爲默認搜索域, 可提升查詢效率.
(2)使用注意事項:
① 目標域的定義, 必需要指定
multiValued="true"
.
② 只複製單個域, 若是被複制域自己就是多值域, 那麼目標域也是多值域 ⇒ 無實際意義;
③ 若複製多個域, 只要其中有一個域是多值域, 那麼目標域就必定是多值域.
動態域經過通配符, 實現了域的模糊匹配, 可以有效避免頻繁地修改schema.xml
文件.
⇒ 修改schema.xml文件後, Solr程序須要從新加載配置文件, 較爲繁瑣.
dynamicField
(動態域) 和 copyField
(複製域)是Solr擴展的域, 在Lucene中沒有與之相關的概念.
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
(1)屬性說明:
name
: 動態域的名稱, 是一個表達式:a)
*
表示匹配任意字符, 只能出如今模式的最前或最後;b) 較長的模式會先作匹配;
c) 若是2個模式同時匹配上, 最早定義的優先匹配.
(2)使用說明:
使用時, 只須要域的名稱與表達式匹配便可. 如
"product_i":"筆記本"
, 直接使用product_i就能夠, 不須要再作其餘定義.
若是經過上面的匹配都沒找到, 能夠設置下述類型的配置, 而後定義一個type看成String處理. 通常不會發生, 但若不定義, 找不到匹配就會報錯.<dynamicField name="*_i" type="ignored" multiValued="true"/>
Solr經過uniqueKey
來指定文檔的主鍵, 默認的, id域被做爲主鍵, 所以id域是必須的.
⇒ 固然用戶能夠自定義主鍵.
<uniqueKey>id</uniqueKey>
Solr中被標記爲required="true"
的字段, 必需要由<uniqueKey>
做惟一標識, 不然創建索引時將報錯.
Solr將根據<uniqueKey>
標識的field (默認就是id) 來決定增量導入時是否重複導入: 若是id相同, 就不會重複導入;
(1) 默認搜索域:
<defaultSearchField>text</defaultSearchField>
若是搜索參數中沒有指定具體的field, 這將做爲默認的域進行搜索.
Solr 6.x版本中已經移除了此參數.
(2) Solr查詢解析器:
<!-- 從Solr 6.6版本開始, 再也不支持defaultOperator --> <solrQueryParser defaultOperator="OR"/>
配置搜索參數短語間的邏輯, 能夠是AND|OR.
(1) 將全部只用於搜索、而不須要做爲結果返回原始值的field(特別是比較大的field)設置爲 stored="false"
;
(2) 將不須要被用於搜索、而只是做爲結果返回的field設置爲 indexed="false"
;
(3) 刪除全部沒必要要的copyField;
(4) 爲了最小化索引字段、提升搜索效率, 將爲全部的text field 都設置 index="false"
, 而後使用copyField將它們都複製到一個總的text field上, 對該text field進行搜索;
(5) 爲了最大化搜索性能, 使用ConcurrentUpdateSolrServer
Java客戶端與Solr交互(使用併發修改服務);
(6) 在服務器端運行JVM, 即設置使用-server
服務端模式, 性能更好; 並使用盡量高級別的Log輸出等級, 避免記錄每一個請求, 減小日誌量.
分詞 | 搜索 | 存儲 | 示例 |
---|---|---|---|
√ | √ | √ | 網頁的標題、內容 |
√ | X | √ | 網頁的發佈時間 |
X | X | √ | 引用的圖片位置 |
√ | √ | √ | 網頁標題、內容 |
不存在不須要索引、不須要分詞、也不須要存儲的字段, 由於這樣的字段在Lucene中無心義.
參考資料
版權聲明
出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)
感謝閱讀, 若是文章有幫助或啓發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜
本文版權歸博主全部, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文連接], 不然博主保留追究相關人員法律責任的權利.