Solr系列三:solr索引詳解(Schema介紹、字段定義詳解、Schema API 介紹)


一、Schema介紹

1. Schema 是什么?

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

2. Schema 的定義方式

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

2.1 默認方式,通過Schema API 來實時配置,模式信息存儲在內核目錄的conf/managed-schema文件中。

2.2 傳統的手工編輯conf/schema.xml的方式,編輯完后需重載集合/內核才會生效。

3. schema兩種配置方式切換

3.1 schema.xml 到 managed schema 

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

Solr重啟時,它發現存儲schema.xml 但不存儲在 managed-schema,它會備份schema.xml,然后改寫schema.xml 為 managed-schema。此后就可以通過Schema API 管理schema了。

3.2 managed schema 到 schema.xml

1 將managed-schema 重命名為 schema.xml

2 將solrconfig.xml 中schemaFactory 的ManagedIndexSchemaFactory去掉(如果存在)

3 增加<schemaFactory class =“ClassicIndexSchemaFactory”/>

4. 查看 D:\solr-7.3.0\server\solr\mycore\conf\managed-schema文件,了解它的構成

 

二、字段定義詳解

 1. 字段定義示例

<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:字段名,必需。字段名可以由字母、數字、下划線構成,不能以數字開頭。以下划線開頭和結尾的名字為保留字段名,如 _version_

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

 default:默認值,如果提交的文檔中沒有該字段的值,則自動會為文檔添加這個默認值。非必需。

2. 字段定義詳解-定義FieldType

(前面定義了字段field,這里我們就有定義字段類型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 的屬性

Solr中提供的 FieldType 類,在 org.apache.solr.schema 包下

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

3. FieldType 的 Analyzer

 對於 solr.TextField or solr.SortableTextField 字段類型,需要為其定義分析器。

<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

 如果該類型字段索引、查詢時需要使用不同的分析器,則需區分配置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

4. 常用的Filter

4.1 Stop Filter 停用詞過濾器

<analyzer>
  <tokenizer class="solr.StandardTokenizerFactory"/>
  <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
</analyzer>

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

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

4.2 Synonym Graph Filter   同義詞過濾器

<analyzer type="index">
  <tokenizer class="solr.StandardTokenizerFactory"/>
  <filter class="solr.SynonymGraphFilterFactory" synonyms="mysynonyms.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="mysynonyms.txt"/>
</analyzer>

同義詞定義語法:

(1)一類一行: 

couch,sofa,divan

(2)=>表示標准化為后面的:

teh => the

huge,ginormous,humungous => large

small => tiny,teeny,weeny

提問:(1)(2)同義詞的定義在索引的時候處理和查詢的時候處理哪種效率更高?

    答:一類一行的在查詢的時候進行處理效率更高,原因是如果在索引的時候處理話要存儲的字段更多,並且在查詢的時候可擴展性更高,如果有新詞出現直接在同義詞文件里面增加新詞,然后重載即可。

      標准化的方式在索引的時候處理的性能更高,原因是存儲的字段更少

練習1:自定義字段過濾停用詞和同義詞

步驟1:

在D:\solr-7.3.0\server\solr\mycore\conf目錄下的停用詞stopwords.txt和同義詞synonyms.txt的txt文件里面分別加入

停用詞:

hello

like

同義詞:

couch,sofa,divan

teh => the

huge,ginormous,humungous => large

small => tiny,teeny,weeny

步驟2:

 在D:\solr-7.3.0\server\solr\mycore\conf目錄下的模式文件managed-schema里面自定義一個字段來進行分詞索引並配置停用詞和同義詞

<!--自定義字段過濾停用詞和同義詞 begin-->
    <fieldType name="myTestField" class="solr.SortableTextField" positionIncrementGap="100" multiValued="true">
      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>
    <!--自定義字段過濾停用詞和同義詞 end-->

步驟3:

重啟solr,在web控制台就可以進行測試查看效果了

練習2:在solr里面集成IKAnalyzer 中文分詞器

步驟1:

在原來學習lucene集成IKAnalyzer的基礎上,為IkAnalyzer實現一個TokenizerFactory(繼承它),接收useSmart參數。

步驟2:

將這三個類打成jar,如 IKAnalyzer-lucene7.3.jar

步驟3:

將這個IKAnalyzer-lucene7.3.jar和 IKAnalyzer的jar 拷貝到web應用的lib目錄下

 

步驟4:

將停用詞和擴展詞的三個配置文件拷貝到應用的classes目錄下

步驟5:

在schema中定義一個FieldType,使用IKAnalyzer適配類

<!--集成IK中文分詞器 里面有停用詞和擴展詞 begin-->
    <fieldType name="ik_zh_CN" class="solr.TextField">
        <analyzer>
            <tokenizer class="com.study.lucene.demo.analizer.ik.IKTokenizer4Lucene7Factory" useSmart="true" /> 
        </analyzer>
    </fieldType>
    <!--集成IK中文分詞器 里面有停用詞和擴展詞 end-->

 步驟6.:

重啟solr,在web控制台就可以進行測試查看效果了

 

 5. 時間字段類型

5.1 Solr中提供的時間字段類型( DatePointField-單個日期, DateRangeField-日期范圍,廢除的TrieDateField )是以時間毫秒數來存儲時間的。要求字段值以ISO-8601標准格式來表示時間:

YYYY-MM-DDThh:mm:ssZ       

示例:

1999-05-20T17:33:18Z

 Z表示是UTC時間(注意:就沒有時區了)

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

1972-05-20T17:33:18.772Z

1972-05-20T17:33:18.77Z

1972-05-20T17:33:18.7Z

公元前:在前面加減號 -

9999后,在前面加加號 +

注意:查詢時如果是直接的時間串,需要用轉移符轉義

datefield:1972-05-20T17\:33\:18.772Z

datefield:"1972-05-20T17:33:18.772Z"

datefield:[1972-05-20T17:33:18.772Z TO *]

5.2  DateRangeField 時間段類型特別說明

DateRangeField用來支持對時間段數據的索引,它遵守時間格式:YYYY-MM-DDThh:mm:ssZ,支持兩種時間段表示方式:

方式一:截斷日期,它表示整個日期跨度的精確指示。

2000-11 表示2000年11月整個月.

2000-11T13 表示2000年11月每天的13點這一個小時

-0009 公元前10年,0000是公元前1年。

方式二:范圍語法 [ TO ]   { TO }

[2000-11-01 TO 2014-12-01] 日到日

[2014 TO 2014-12-01] 2014年開始到2014-12-01止.

[* TO 2014-12-01] 2014-12-01(含)前.

5.3 時間數學表達式

Solr中還支持用 NOW +- 時間的數學表達式來靈活表示時間。語法 NOW +- 帶單位的時間數,/單位 截斷。可用來表示時間段。

NOW+2MONTHS:現在的時間加上2個月

NOW-1DAY:現在的時間減去1天

NOW/HOUR:當前時間取整到小時

NOW+6MONTHS+3DAYS/DAY:當前時間+6個月+3天,然后取整到天

1972-05-20T17:33:18.772Z+6MONTHS+3DAYS/DAY

注意:運算順序是從左往右,只有加減取整運算,沒有乘除運算

NOW在查詢中使用時,可為NOW指定值:

q=solr&fq=start_date:[* TO NOW]&NOW=1384387200000

沒有&后面的賦值NOW就是當前時間

6. EnumFieldType 枚舉字段類別說明

EnumFieldType  用於字段值是一個枚舉集,且排序順序可預定的情況,如新聞分類這樣的字段。定義非常簡單:

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

說明:

enumsConfig:指定枚舉值的配置文件,絕對路徑或相對內核conf/的相對路徑

enumName:指定配置文件的枚舉名。排序順序是按配置的順序。

docValues : 枚舉類型字段必須設置 true;

枚舉配置示例:

<?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>
</enumsConfig>

7. dynamic Field  動態字段

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

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

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

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

也可以是前綴,如    name=“i_*”

8. CopyField    復制字段

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

1、將多個字段內容填充到一個字段,來進行搜索。如用戶輸入了多個搜索字段,程序就把這些字段放入一個字段里面進行搜索

2、對同一個字段內容進行不同的分詞過濾,創建一個新的可搜索字段

定義方式:

1、先定義一個普通字段

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

2、定義復制字段

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

把cat和name這兩個字段都復制到cc_all這個字段里面

問:復制字段時,source可以是動態字段嗎?

  答:可以

8. uniqueKey 唯一鍵

指定用作唯一鍵的字段,非必需。

<uniqueKey>id</uniqueKey>

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

注意:唯一鍵是業務的唯一字段,不是document的id

9. Similarity 相關性計算類配置

問:什么是相關性計算?

  答:相關性計算指的是根據某個字段進行搜索時,把與搜索最匹配的排在前面

如果默認的相關性計算模型BM25Similarity不滿足你應用的特殊需要,你可在schema中指定全局的或字段類型局部的相關性計算類

示例:

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

10. 小結:字段定義詳解

 

三、Schema API 介紹

前面我們都是采用自己在schema模式配置文件里面自己編寫配置文件的方式來定義模式,其實我們還可以使用schema API的方式來動態的定義模式,不用自己手工編寫配置文件,這樣更加方便

 

1、Schema操作API總體介紹

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

1.1 更新Schema:

發送 post請求到 /collection/schema  ,以JSON格式提交數據,在json中說明你要進行的更新操作及對應的數據(一次請求可進行多個操作)

1.2 更新操作定義

add-field: 添加一個新字段.
delete-field: 刪除一個字段.
replace-field: 替換一個字段,修改.
add-dynamic-field: 添加一個新動態字段. delete-dynamic-field: 刪除一個動態字段 replace-dynamic-field: 替換一個已存在的動態字段
add-field-type: 添加一個fieldType. delete-field-type: 刪除一個fieldType. replace-field-type: 更新一個存在的fieldType
add-copy-field: 添加一個復制字段規則. delete-copy-field: 刪除一個復制字段規則.

 2、V1、V2兩個版本API說明

V1老版本的api,V2新版本的API,當前兩個版本的API都支持,將來會統一到新版本。兩個版本的API只是請求地址上的區別,參數沒區別。

V1: http://localhost:8983/solr/mycore/schema

V2: http://localhost:8983/api/cores/mycore/schema

說明:

mycore:solr里面定義的內核或者集合的名稱

3、FieldType字段類別操作

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

使用postman來發送添加的請求:

請求地址:http://localhost:8983/solr/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "add-field-type": {
        "name": "myNewTxtField",
        "class": "solr.TextField",
        "positionIncrementGap": "100",
        "analyzer": {
            "tokenizer": {
                "class": "solr.WhitespaceTokenizerFactory"
            },
            "filters": [
                {
                    "class": "solr.WordDelimiterFilterFactory",
                    "preserveOriginal": "0"
                }
            ]
        }
    }
}

 postman模擬請求:

 

 

在solr的web控制台查看添加的字段

 添加字段時包含索引分析器和查詢分析器:

{
    "add-field-type": {
        "name": "myNewTextField",
        "class": "solr.TextField",
        "indexAnalyzer": {
            "tokenizer": {
                "class": "solr.PathHierarchyTokenizerFactory",
                "delimiter": "/"
            }
        },
        "queryAnalyzer": {
            "tokenizer": {
                "class": "solr.KeywordTokenizerFactory"
            }
        }
    }
}

 3.2 刪除一個字段類別 delete-field-type

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "delete-field-type": {
        "name": "myNewTxtField"
    }
}

3.3 替換一個字段類別 replace-field-type

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "replace-field-type": {
        "name": "myNewTxtField",
        "class": "solr.TextField",
        "positionIncrementGap": "100",
        "analyzer": {
            "tokenizer": {
                "class": "solr.StandardTokenizerFactory"
            }
        }
    }
}

4、Field 字段操作

4.1 添加一個字段 add-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "add-field": {
        "name": "sell_by",
        "type": "myNewTxtField",
        "stored": true
    }
}

 4.2 刪除一個字段 delete-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "delete-field": {
        "name": "sell_by"
    }
}

4.3 替換一個字段 replace-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "replace-field": {
        "name": "sell_by",
        "type": "date",
        "stored": false
    }
}

5、dynamicField 動態字段操作

5.1 添加一個動態字段 add-dynamic-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "add-dynamic-field": {
        "name": "*_s",
        "type": "string",
        "stored": true
    }
}

5.2 刪除一個動態字段 delete-dynamic-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "delete-dynamic-field": {
        "name": "*_s"
    }
}

5.3 替換一個動態字段 replace-dynamic-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
  "replace-dynamic-field":{
     "name":"*_s",
     "type":"text_general",
     "stored":false }
}

6、copyField 復制字段操作

6.1 添加復制字段 add-copy-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "add-copy-field": {
        "source": "shelf",
        "dest": [
            "location",
            "catchall"
        ]
    }
}

6.2 刪除復制字段 delete-copy-field

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "delete-copy-field": {
        "source": "shelf",
        "dest": "location"
    }
}

7. 一次請求多個操作示例

7.1 同時添加字段類型和字段

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "add-field-type": {
        "name": "myNewTxtField",
        "class": "solr.TextField",
        "positionIncrementGap": "100",
        "analyzer": {
            "tokenizer": {
                "class": "solr.WhitespaceTokenizerFactory"
            },
            "filters": [
                {
                    "class": "solr.WordDelimiterFilterFactory",
                    "preserveOriginal": "0"
                }
            ]
        }
    },
    "add-field": {
        "name": "sell_by",
        "type": "myNewTxtField",
        "stored": true
    }
}

7.2 一次添加多個字段

請求地址:http://localhost:8983/api/cores/mycore/schema

請求方式:post

設置頭信息為:Content-type:application/json

參數:json格式的參數

{
    "add-field": [
        {
            "name": "shelf",
            "type": "myNewTxtField",
            "stored": true
        },
        {
            "name": "location",
            "type": "myNewTxtField",
            "stored": true
        }
    ]
}

8、獲取schema信息

8.1 獲取整個schema

GET /collection/schema

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

http://localhost:8983/api/cores/mycore/schema?wt=xml

 

8.2 獲取字段

GET /collection/schema/fields
GET /collection/schema/fields/fieldname
請求參數有:
wt:   json/xml            fl:指定需要返回的字段名,以逗號或空格間隔
showDefaults:true/false ,是否返回字段的默認屬性
includeDynamic:true/false,在path中帶有fieldname  或指定了 fl的情況下才有用。

獲取所有字段: 

http://localhost:8983/api/cores/mycore/schema/fields

 

獲取指定字段: 

http://localhost:8983/api/cores/mycore/schema/fields/_root_

 

8.3 獲取動態字段

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

可用請求參數:wt、showDefaults

http://localhost:8983/api/cores/mycore/schema/dynamicfields?wt=xml

8.4 獲取字段類別

GET /collection/schema/fieldtypes
GET /collection/schema/fieldtypes/name

 可用請求參數:wt、showDefaults

 http://localhost:8983/api/cores/mycore/schema/fieldtypes?wt=xml

 

8.5 獲取復制字段

 GET /collection/schema/copyfields

 可用請求參數:wt、 source.fl、 dest.fl

8.6 獲取其他信息

GET /collection/schema/name               獲取schema的name
GET /collection/schema/version    獲取schema的版本
GET /collection/schema/uniquekey    獲取唯一鍵字段
GET /collection/schema/similarity    獲取全局相關性計算類

可用請求參數:wt

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM