Solr索引詳解

1、Schema介紹

schema 是什么?

Schema:模式,是集合/內(nèi)核中字段的定義,讓solr知道集合/內(nèi)核包含哪些字段、字段的數(shù)據(jù)類型、字段該索引的存儲。

schema 的定義方式

solr中提供了兩種方式來配置schema,兩者只能選其一:

  1. 默認(rèn)方式,通過Schema API 來實(shí)現(xiàn)配置,模式信息存儲在 內(nèi)核目錄的conf/managed-schema文件中。
  2. 傳統(tǒng)的手工編輯 conf/schema.xml的方式,編輯完后需要重載集合/內(nèi)核才會生效。

schema 兩種配置方式切換

  • schema.xml 到 managed schema
    只需要將 solrconfig.xml 中的
    <schemaFactory class =“ClassicIndexSchemaFactory”/> 去掉,或改為 ManagedIndexSchemaFactory。

solr重啟時,他發(fā)現(xiàn)存儲 schema.xml 但不存儲在 managed-schema,他會備份 schema.xml,然后改寫 schema.xml 為 managed-schema。此后既可以通過schema API 管理schema了。

  • managed schema 到 schema.xml
  1. 將 managed schema 重命名為 schema.xml
  2. 將 solrconfig.xml 中 schemaFactory 的 ManagedIndexSchemaFactory 去掉(如果存在)
  3. 增加 <schemaFactory class =“ClassicIndexSchemaFactory”/>

solr還支持無模式方式,solr會猜測該如何索引字段,不可用在生產(chǎn)環(huán)境下。

managed-schema文件構(gòu)成

<?xml version="1.0" encoding="UTF-8" ?>
<schema version="1.6">
    <field .../>  #字段
    <dynamicField .../> #動態(tài)字段
    <uniqueKey>id</uniqueKey> #唯一key的指定
    <copyField .../> #拷貝字段
    <fieldType ...> #字段存儲類型
        <analyzer type="index">
            <tokenizer .../>
            <filter ... />
        </analyzer>
        <analyzer type="query">
            <tokenizer.../>
            <filter ... />
        </analyzer>
    </fieldType>
</schema>

2、字段定義詳解

字段定義示例

<field name="name" type="text_general" indexed="true" stored="true"/> 
<field name="includes" type="text_general" indexed="true" stored="true" termVectors="true" termPositions="true" termOffsets="true" />

字段屬性說明

  • name:字段名,必需。字段名可以由字母、數(shù)字、下劃線構(gòu)成,不能以數(shù)字開頭。以下劃線開頭和結(jié)尾的名字為保留字段名,如 version

  • type:字段的 fieldType名,必需。為 FieldType 定義的name屬性值。

  • default:默認(rèn)值,如果提交的文檔中沒有該字段值,則自動會為文檔添加這個默認(rèn)值。非必需(indexed,stored,termVectors等屬性)。

  • 字段中用于覆蓋fieldType的可選屬性說明

    覆蓋fieldType的可選屬性說明

FieldType(字段類型)詳解

定義在索引時該如何分詞、索引、存儲字段,在查詢時該如何對查詢串分詞。

<fieldType name="managed_en" class="solr.TextField" positionIncrementGap="100">
  #索引時
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.ManagedStopFilterFactory" managed="english" />
    <filter class="solr.ManagedSynonymGraphFilterFactory" managed="english" />
    <filter class="solr.FlattenGraphFilterFactory"/>
  </analyzer>
  #查詢時
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.ManagedStopFilterFactory" managed="english" />
    <filter class="solr.ManagedSynonymGraphFilterFactory" managed="english" />
  </analyzer>
</fieldType>

FieldType 的屬性說明

FieldType 的屬性說明

solr中提供的FieldType 類(class屬性),在org.apache.solr.schema 包下

http://lucene.apache.org/solr/guide/7_3/field-types-included-with-solr.html

FieldType 的 Analyzer

  • 對于 solr.TextField or solr.SorttableTextField 字段類型,需要為其定義分析器。
<fieldType name="nametext" class="solr.TextField">
 #分析器
 <analyzer class="org.apache.lucene.analysis.core.WhitespaceAnalyzer"/>
</fieldType>
  • 可以直接通過class屬性指定分析器類,必須繼承
org.apache.lucene.analysis.Analyzer 
  • 也可靈活地組合分詞器、過濾器:
<fieldType name="nametext" class="solr.TextField">
  <analyzer>
    #分詞器
    <tokenizer class="solr.StandardTokenizerFactory"/>
    #過濾器
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.StopFilterFactory"/>
  </analyzer>
</fieldType>

org.apache.solr.analysis 包下的類可以簡寫為 solr.xxx

  • 如果該類型字段索引、查詢時需要使用不同的分析器,則需區(qū)分配置analyzer
<fieldType name="nametext" class="solr.TextField">
  #索引
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.KeepWordFilterFactory" words="keepwords.txt"/>
    <filter class="solr.SynonymFilterFactory" synonyms="syns.txt"/>
  </analyzer>
  #查詢
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

Solr中提供的tokenizer: http://lucene.apache.org/solr/guide/7_3/tokenizers.html
Solr中提供的 fiter: http://lucene.apache.org/solr/guide/7_3/filter-descriptions.html

常用Filter

  • Stop Filter 停用此過濾器
<analyzer>
  <tokenizer class="solr.StandardTokenizerFactory"/>
  #停用詞過濾器
  <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
</analyzer>

words屬性指定停用詞文件的絕對路徑相對 conf/ 目錄的相對路徑

停用詞定義語法:一行一個

  • Synonym Graph Filter 同義詞過濾器
<analyzer type="index">
  <tokenizer class="solr.StandardTokenizerFactory"/>
  #同義詞過濾器
  <filter class="solr.SynonymGraphFilterFactory" synonyms="my_synonyms.txt"/>
  <filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
</analyzer>
<analyzer type="query">
  <tokenizer class="solr.StandardTokenizerFactory"/>
  #同義詞過濾器
  <filter class="solr.SynonymGraphFilterFactory" synonyms="my_synonyms.txt"/>
</analyzer>

同義詞定義語法:一類一行,=>表示標(biāo)準(zhǔn)化為后面的。

couch,sofa,divan
teh => the
huge,ginormous,humungous => large
small => tiny,teeny,weeny

集成IKAnalyzer 中文分詞器

1、在原來學(xué)習(xí)lucene集成IKAnalyzer的基礎(chǔ)上,為IkAnalyzer實(shí)現(xiàn)一個TokenizerFactory(繼承它),接收useSmart參數(shù)。
2、將這三個類打成jar,如 IKAnalyzer-lucene7.3.jar
3、將這個jar和 IKAnalyzer的jar 拷貝到web應(yīng)用的lib目錄下
4、將三個配置文件拷貝到應(yīng)用(WEB_INF下)的classes目錄下
5、在schema中定義一個FieldType,使用IKAnalyzer適配類

<fieldType name=“zh_CN _text" class="solr.TextField">
    <analyzer>
        <tokenizer class="com.dongnao.lucene.demo.analizer.ik.IKTokenizer4Lucene7Factory" useSmart="true" /> 
    </analyzer>
</fieldType>

時間字段類型特別說明

  • Solr 中提供的時間字段類型( DatePointField(時間點(diǎn)),DateRangeField(時間段),廢除的TrieDateField )是以時間毫秒數(shù)存儲時間的。要求字段值ISO-8601標(biāo)準(zhǔn)格式來表示時間:
YYYY-MM-DDThh:mm:ssZ

Z表示是UTC時間(注意:就沒有失去了),例如:

1999-05-20T17:33:18Z

秒上可以帶小數(shù)來表示毫秒數(shù),超出精度部分會被忽略:

1972-05-20T17:33:18.772Z
1972-05-20T17:33:18.77Z
1972-05-20T17:33:18.7Z

公元前:在前面加減號 -
9999后,在前面加加號 +
注意:查詢時如果是直接的時間串,需要用轉(zhuǎn)移符轉(zhuǎn)義:

datefield:1972-05-20T17\:33\:18.772Z  #需要轉(zhuǎn)義
datefield:"1972-05-20T17:33:18.772Z"  #不需要轉(zhuǎn)義
datefield:[1972-05-20T17:33:18.772Z TO *]  #不需要轉(zhuǎn)義

DateRangField 時間段類型特別說明

  • DateRangeField用來支持對 時間段數(shù)據(jù)索引 ,它遵守上一頁講到的時間格式,支持兩種時間段表示方式:
    • 方式一:截?cái)嗳掌?,它表示整個日期跨度的精確指示。
    • 方式二:范圍語法 [ TO ] { TO }
2000-11         表示2000年11月整個月.
2000-11T13      表示200年11月每天的13點(diǎn)這一個小時
-0009           公元前10年,0000是公元前1年。
[2000-11-01 TO 2014-12-01]      日到日
[2014 TO 2014-12-01]    2014年開始到2014-12-01止.
[* TO 2014-12-01]       2014-12-01(含)前.

時間數(shù)學(xué)表達(dá)式

  • Solr中還支持用 NOW +- 時間的數(shù)學(xué)表達(dá)式來靈活表示時間。
    語法: NOW +- 帶單位的時間數(shù),/ 單位 截?cái)???捎脕肀硎緯r間段。
NOW+2MONTHS    # + 兩個月
NOW-1DAY    # + 一天
NOW/HOUR    # 當(dāng)前時間截?cái)嗟叫r
NOW+6MONTHS+3DAYS/DAY    # 當(dāng)前時間 + 六個月 + 三天 截?cái)嗟降教?1972-05-20T17:33:18.772Z+6MONTHS+3DAYS/DAY

NOW查詢中使用時,可為NOW指定值。
例如:
q=solr&fq=start_date:[* TO NOW]&NOW=1384387200000
沒有加粗的部分系統(tǒng)默認(rèn)NOW為系統(tǒng)時間,有加粗的部分NOW就為1384387200000

注意:大括號 {} 不包含邊界時間,中括號 [] 包含邊界時間

EnumFieldType 枚舉字段類別說明

  • EnumFieldType 用于字段值是一個枚舉集,且排序順序可預(yù)訂的情況,如新聞分類這樣的字段,定義非常簡單:

<fieldType name="priorityLevel" class="solr.EnumFieldType" docValues="true" enumsConfig="enumsConfig.xml" enumName="priority"/>

  • enumsConfig:指定枚舉值的配置文件,絕對路徑或相對 內(nèi)核 conf/ 的相對路徑
  • enumName:指定配置文件的枚舉名。排序順序是按配置的排序。
  • docValues:枚舉類型字段必須設(shè)置 true。

枚舉xml配置文件

<?xml version="1.0" ?>
<enumsConfig>
  <enum name="priority">
    <value>Not Available</value>
    <value>Low</value>
    <value>Medium</value>
    <value>High</value>
    <value>Urgent</value>
  </enum>
  <enum name="risk">
    <value>Unknown</value>
    <value>Very Low</value>
    <value>Low</value>
    <value>Medium</value>
    <value>High</value>
    <value>Critical</value>
  </enum>
  # 創(chuàng)建一個新聞類別的枚舉字段類別,枚舉值:時事、財(cái)經(jīng)、科技、體育、娛樂、教育、汽車
  <enum name="new_cat">
    <value>時事</value>
    <value>財(cái)經(jīng)</value>
    <value>科技</value>
    <value>體育</value>
    <value>娛樂</value>
    <value>教育</value>
    <value>汽車</value> 
  </enum>
</enumsConfig>

fileType調(diào)用新聞類枚舉值:
<fieldType name="catLevel" class="solr.EnumFieldType" docValues="true" enumsConfig="enumsConfig.xml" enumName="new_cat"/>

dynamic Field 動態(tài)字段

問: 如果模式中有近百個字段需要定義,其中有很多字段的定義是相同,重復(fù)定義是不是很煩?

可不可以定一個規(guī)則,字段名以某前綴開頭結(jié)尾的是相同的定義配置,那這些重復(fù)的字段就只需要配置一個,保證提交的字段名稱遵守這個前綴、后綴即可。這就是動態(tài)字段。

如:整型字段都是一樣的定義,則可以定義一個動態(tài)字段如下:

<dynamicField name="*_i" type=“my_int" indexed="true" stored="true"/>
#也可以是前綴,如:name="i_*"

CopyField 復(fù)制字段

復(fù)制字段允許將 一個或多個 字段的值填充到一個字段中。它的用途有兩種:

1、將多個字段內(nèi)容填充到一個字段,來進(jìn)行搜索
2、對同一個字段內(nèi)容進(jìn)行不同的分詞過濾,創(chuàng)建一個新的可搜索字段

定義方式:

1、先定義一個普通字段

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

2、定義復(fù)制字段

<copyField source="cat" dest="cc_all"/>
<copyField source="name" dest="cc_all"/>

復(fù)制字段時,source 可以是動態(tài)字段。

uniqueKey 唯一鍵

指定用作唯一的字段,非必需。在刪除文檔的時候可以通過唯一鍵刪除。

#業(yè)務(wù)id
<uniqueKey>id</uniqueKey>

唯一鍵字段不可以是保留字段、復(fù)制字段,且不能分詞。

Similarity 相關(guān)性計(jì)算類配置

如果默認(rèn)的相關(guān)性計(jì)算模型 BM25Similarity 不滿足你應(yīng)用的特殊需求,你可在schema中指定全局的字段類型局部相關(guān)性計(jì)算類。

<similarity class="solr.SchemaSimilarityFactory">
  <str name="defaultSimFromFieldType">text_dfr</str>
</similarity>
<fieldType name="text_dfr" class="solr.TextField">
  <analyzer ... />
  <similarity class="solr.DFRSimilarityFactory">
    <str name="basicModel">I(F)</str>
    <str name="afterEffect">B</str>
    <str name="normalization">H3</str>
    <float name="mu">900</float>
  </similarity>
</fieldType>

3、Schema API介紹

Schema API

Schema 操作API總體介紹

Solr中強(qiáng)烈推薦使用 Schema API 來* 管理集合/內(nèi)核* 的模式信息,可以 讀、寫 模式信息。通過API來更新模式信息,solr將 自動重載內(nèi)核 。但是請注意:模式修改并不會自動重新索引已索引的文檔,只會對后續(xù)的文檔起作用,如果必要,你需要手動重新索引(刪除原來的,重新提交文檔)

更新 Schema

發(fā)送 post 請求 /collection/schema(/集合或內(nèi)核的名字/schema),以JSON格式提交數(shù)據(jù),在json中說明你要進(jìn)行的更新操作及對應(yīng)的數(shù)據(jù)(一次請求可進(jìn)行多個操作)。

  • 更新操作定義
add-field: 添加一個新字段.
delete-field: 刪除一個字段.
replace-field: 替換一個字段,修改.
add-dynamic-field: 添加一個新動態(tài)字段.
delete-dynamic-field: 刪除一個動態(tài)字段
replace-dynamic-field: 替換一個已存在的動態(tài)字段
add-field-type: 添加一個fieldType.
delete-field-type: 刪除一個fieldType.
replace-field-type: 更新一個存在的fieldType
add-copy-field: 添加一個復(fù)制字段規(guī)則.
delete-copy-field: 刪除一個復(fù)制字段規(guī)則.

V1、V2 兩個版本API說明

V1老版本的api,V2新版本的API,當(dāng)前兩個版本的API都支持,將來會統(tǒng)一到新版本。兩個版本的API只是請求地址上的區(qū)別,參數(shù)沒區(qū)別。

V1:
http://localhost:8983/solr/gettingstarted/schema
V2: http://localhost:8983/api/cores/gettingstarted/schema

FieldType 字段類別操作

  • 添加一個字段類別 add-field-type

一個Analyzer

#linux 中請求方式
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-field-type" : {
     "name":"myNewTxtField",
     "class":"solr.TextField",
     "positionIncrementGap":"100", ##避免臨近查詢,跨度查詢出錯的
     "analyzer" : {
        "tokenizer":{
           "class":"solr.WhitespaceTokenizerFactory" },
        "filters":[{
           "class":"solr.WordDelimiterFilterFactory",
           "preserveOriginal":"0" }]}}
}' http://localhost:8983/solr/gettingstarted/schema

兩個Analyzer

curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-field-type":{
     "name":"myNewTextField",
     "class":"solr.TextField",
     "indexAnalyzer":{
        "tokenizer":{
           "class":"solr.PathHierarchyTokenizerFactory",
           "delimiter":"/" }},
     "queryAnalyzer":{
        "tokenizer":{
           "class":"solr.KeywordTokenizerFactory" }}}
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 刪除一個字段類別 delete-field-type
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "delete-field-type":{ "name":"myNewTxtField" }
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 替換一個字段類別 replace-field-type
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "replace-field-type":{
     "name":"myNewTxtField",  #根據(jù)名稱來進(jìn)行替換
     "class":"solr.TextField",
     "positionIncrementGap":"100",
     "analyzer":{
        "tokenizer":{
           "class":"solr.StandardTokenizerFactory" }}}
}' http://localhost:8983/api/cores/gettingstarted/schema

Field 字段操作

  • 添加一個字段 add-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-field":{
     "name":"sell_by",
     "type":"pdate",
     "stored":true }
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 刪除一個字段 delete-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "delete-field" : { "name":"sell_by" }
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 替換一個字段 replace-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "replace-field":{
     "name":"sell_by",
     "type":"date",
     "stored":false }
}' http://localhost:8983/api/cores/gettingstarted/schema

dynamicField 動態(tài)字段操作

  • 添加一個動態(tài)字段 add-dynamic-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-dynamic-field":{
     "name":"*_s",
     "type":"string",
     "stored":true }
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 刪除一個動態(tài)字段 delete-dynamic-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "delete-dynamic-field":{ "name":"*_s" }
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 替換一個動態(tài)字段 replace-dynamic-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "replace-dynamic-field":{
     "name":"*_s",
     "type":"text_general",
     "stored":false }
}' http://localhost:8983/solr/gettingstarted/schema

copyField 復(fù)制字段操作

  • 添加復(fù)制字段 add-copy-field

curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-copy-field":{
     "source":"shelf",
     "dest":[ "location", "catchall" ]}
}' http://localhost:8983/api/cores/gettingstarted/schema
  • 刪除復(fù)制字段 delete-copy-field
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "delete-copy-field":{ "source":"shelf", "dest":"location" }
}' http://localhost:8983/api/cores/gettingstarted/schema

一次請求多個操作示例

  • 示例一
curl -X POST -H 'Content-type:application/json' --data-binary '{ 
  "add-field-type":{ #1
     "name":"myNewTxtField",
     "class":"solr.TextField",
     "positionIncrementGap":"100",
     "analyzer":{"tokenizer":{
           "class":"solr.WhitespaceTokenizerFactory" },
        "filters":[{
           "class":"solr.WordDelimiterFilterFactory",
           "preserveOriginal":"0" }]}},
   "add-field" : { #2
      "name":"sell_by",
      "type":"myNewTxtField",
      "stored":true }
}' http://localhost:8983/solr/gettingstarted/schema
  • 示例二
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-field":[
     { "name":"shelf",  #1
       "type":"myNewTxtField",
       "stored":true },
     { "name":"location",  #2
       "type":"myNewTxtField",
       "stored":true }]
}' http://localhost:8983/solr/gettingstarted/schema

獲取schema信息

  • 獲取整個schema
GET /collection/schema
#GET /集合或者內(nèi)核名稱/schema

可以通過 wt 請求參數(shù)指定返回的格式:json,xml,schema.xml

http://localhost:8983/api/cores/mycore/schema?wt=xml
  • 獲取字段
GET /collection/schema/fields
GET /collection/schema/fields/fieldname

請求參數(shù)

  • wt:json/xml

  • fl:指定需要返回的字段名,以逗號或空格間隔

  • showDefaults:true/false ,是否返回字段的默認(rèn)屬性

  • includeDynamic:true/false,在path中帶有fieldname 或指定了 fl的情況下才有用。

  • 獲取動態(tài)字段

GET /collection/schema/dynamicfields
GET /collection/schema/dynamicfields/name

可用請求參數(shù):wt、showDefaults

http://localhost:8983/api/cores/mycore/schema/dynamicfields?wt=xml
  • 獲取字段類別
GET /collection/schema/fieldtypes
GET /collection/schema/fieldtypes/name

可用請求參數(shù):wt、showDefaults

http://localhost:8983/api/cores/mycore/schema/fieldtypes?wt=xml
  • 獲取復(fù)制字段
GET /collection/schema/copyfields

可用請求參數(shù):wt、source.fl、dest.fl

  • 獲取其他信息
GET /collection/schema/name        獲取schema的name
GET /collection/schema/version   獲取schema的版本
GET /collection/schema/uniquekey     獲取唯一鍵字段
GET /collection/schema/similarity    獲取全局相關(guān)性計(jì)算類

可用請求參數(shù):wt

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容