Solr Schema.xml分析

Solr Schema.xml分析
java

 

1、字段配置(schema)數據庫

schema.xml位於solr/conf/目錄下,相似於數據表配置文件,apache

定義了加入索引的數據的數據類型,主要包括type、fields和其餘的一些缺省設置。服務器

一、先來看下type節點,這裏面定義FieldType子節點,包括name,class,positionIncrementGap等一些參數。網絡

  • name:就是這個FieldType的名稱。app

  • 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,包括分詞和過濾,以下
    ui

    複製代碼

    <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節點內定義具體的字段(相似數據庫的字段),含有如下屬性:this

    • name:字段名google

    • type:以前定義過的各類FieldType

    • indexed:是否被索引

    • stored:是否被存儲(若是不須要存儲相應字段值,儘可能設爲false)

    • multiValued:是否有多個值(對可能存在多值的字段儘可能設置爲true,避免建索引時拋出錯誤)

    •  _version節點和root節點是必須保留的,不能刪除

      複製代碼

      <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>

      複製代碼

  三、建議創建一個拷貝字段,將全部的 全文本 字段複製到一個字段中,以便進行統一的檢索:

          如下是拷貝設置:       

<copyField source="name" dest="all"/><copyField source="summary" dest="all"/>

   

     四、動態字段,沒有具體名稱的字段,用dynamicField字段

          如:name爲*_i,定義它的type爲int,那麼在使用這個字段的時候,任務以_i結果的字段都被認爲符合這個定義。如name_i, school_i

< dynamicField   name = "*_i"    type = "int"      indexed = "true"    stored = "true" />    < dynamicField   name = "*_s"    type = "string"    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

<fieldTypename="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:可選屬性,定義在同一個文檔中此類型數據的空白間隔,避免短語匹配錯誤。

  • positionIncrementGap=100  只對 multiValue = true 的fieldType有意義。

<tokenizerclass="solr.WhitespaceTokenizerFactory" />

空格分詞,精確匹配。

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

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

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

同義詞

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

在禁用字(stopword)刪除後,在短語間增長間隔

stopword:即在創建索引過程當中(創建索引和搜索)被忽略的詞,好比is this等經常使用詞。在conf/stopwords.txt維護。

四、fields

<fieldname="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:若是沒有屬性須要修改,就能夠用這個標識下。

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

一應俱全(有點誇張)的field,包含全部可搜索的text fields,經過copyField實現。

<copyFieldsource="cat" dest="text" />

<copyFieldsource="name" dest="text" />

<copyFieldsource="manu" dest="text" />

<copyFieldsource="features" dest="text" />

<copyFieldsource="includes" dest="text" />

在添加索引時,將全部被拷貝field(如cat)中的數據拷貝到text field中

做用:

  • 將多個field的數據放在一塊兒同時搜索,提供速度

  • 將一個field的數據拷貝到另外一個,能夠用2種不一樣的方式來創建索引。

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

若是一個field的名字沒有匹配到,那麼就會用動態field試圖匹配定義的各類模式。

  • "*"只能出如今模式的最前和最後

  • 較長的模式會被先去作匹配

  • 若是2個模式同時匹配上,最早定義的優先

<dynamicFieldname="*" type="ignored" multiValued="true" />

若是經過上面的匹配都沒找到,能夠定義這個,而後定義個type,當String處理。(通常不會發生)

但若不定義,找不到匹配會報錯。

五、其餘一些標籤

<uniqueKey>id</uniqueKey>

文檔的惟一標識, 必須填寫這個field(除非該field被標記required="false"),不然solr創建索引報錯。

<defaultSearchField>text</defaultSearchField>

若是搜索參數中沒有指定具體的field,那麼這是默認的域。

<solrQueryParserdefaultOperator="OR" />

配置搜索參數短語間的邏輯,能夠是"AND|OR"。

相關文章
相關標籤/搜索