美文网首页
Solr索引详解

Solr索引详解

作者: WinnXUDONG | 来源:发表于2018-06-28 13:56 被阅读0次

    1、Schema介绍

    schema 是什么?

    Schema:模式,是集合/内核中字段的定义,让solr知道集合/内核包含哪些字段、字段的数据类型、字段该索引的存储。

    schema 的定义方式

    solr中提供了两种方式来配置schema,两者只能选其一:

    1. 默认方式,通过Schema API 来实现配置,模式信息存储在 内核目录的conf/managed-schema文件中。
    2. 传统的手工编辑 conf/schema.xml的方式,编辑完后需要重载集合/内核才会生效。

    schema 两种配置方式切换

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

    solr重启时,他发现存储 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会猜测该如何索引字段,不可用在生产环境下。

    managed-schema文件构成

    <?xml version="1.0" encoding="UTF-8" ?>
    <schema version="1.6">
        <field .../>  #字段
        <dynamicField .../> #动态字段
        <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:字段名,必需。字段名可以由字母、数字、下划线构成,不能以数字开头。以下划线开头和结尾的名字为保留字段名,如 version

    • type:字段的 fieldType名,必需。为 FieldType 定义的name属性值。

    • default:默认值,如果提交的文档中没有该字段值,则自动会为文档添加这个默认值。非必需(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

    • 如果该类型字段索引、查询时需要使用不同的分析器,则需区分配置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>
    

    同义词定义语法:一类一行,=>表示标准化为后面的。

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

    集成IKAnalyzer 中文分词器

    1、在原来学习lucene集成IKAnalyzer的基础上,为IkAnalyzer实现一个TokenizerFactory(继承它),接收useSmart参数。
    2、将这三个类打成jar,如 IKAnalyzer-lucene7.3.jar
    3、将这个jar和 IKAnalyzer的jar 拷贝到web应用的lib目录下
    4、将三个配置文件拷贝到应用(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(时间点),DateRangeField(时间段),废除的TrieDateField )是以时间毫秒数存储时间的。要求字段值ISO-8601标准格式来表示时间:
    YYYY-MM-DDThh:mm:ssZ
    

    Z表示是UTC时间(注意:就没有失去了),例如:

    1999-05-20T17:33:18Z
    

    秒上可以带小数来表示毫秒数,超出精度部分会被忽略:

    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 *]  #不需要转义
    

    DateRangField 时间段类型特别说明

    • DateRangeField用来支持对 时间段数据索引 ,它遵守上一页讲到的时间格式,支持两种时间段表示方式:
      • 方式一:截断日期,它表示整个日期跨度的精确指示。
      • 方式二:范围语法 [ TO ] { TO }
    2000-11         表示2000年11月整个月.
    2000-11T13      表示200年11月每天的13点这一个小时
    -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(含)前.
    

    时间数学表达式

    • Solr中还支持用 NOW +- 时间的数学表达式来灵活表示时间。
      语法: NOW +- 带单位的时间数,/ 单位 截断。可用来表示时间段。
    NOW+2MONTHS    # + 两个月
    NOW-1DAY    # + 一天
    NOW/HOUR    # 当前时间截断到小时
    NOW+6MONTHS+3DAYS/DAY    # 当前时间 + 六个月 + 三天 截断到到天
    1972-05-20T17:33:18.772Z+6MONTHS+3DAYS/DAY
    

    NOW查询中使用时,可为NOW指定值
    例如:
    q=solr&fq=start_date:[* TO NOW]&NOW=1384387200000
    没有加粗的部分系统默认NOW为系统时间,有加粗的部分NOW就为1384387200000

    注意:大括号 {} 不包含边界时间,中括号 [] 包含边界时间

    EnumFieldType 枚举字段类别说明

    • EnumFieldType 用于字段值是一个枚举集,且排序顺序可预订的情况,如新闻分类这样的字段,定义非常简单:

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

    • enumsConfig:指定枚举值的配置文件,绝对路径或相对 内核 conf/ 的相对路径
    • enumName:指定配置文件的枚举名。排序顺序是按配置的排序。
    • docValues:枚举类型字段必须设置 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>
      # 创建一个新闻类别的枚举字段类别,枚举值:时事、财经、科技、体育、娱乐、教育、汽车
      <enum name="new_cat">
        <value>时事</value>
        <value>财经</value>
        <value>科技</value>
        <value>体育</value>
        <value>娱乐</value>
        <value>教育</value>
        <value>汽车</value> 
      </enum>
    </enumsConfig>
    

    fileType调用新闻类枚举值:
    <fieldType name="catLevel" class="solr.EnumFieldType" docValues="true" enumsConfig="enumsConfig.xml" enumName="new_cat"/>

    dynamic Field 动态字段

    问: 如果模式中有近百个字段需要定义,其中有很多字段的定义是相同,重复定义是不是很烦?

    可不可以定一个规则,字段名以某前缀开头结尾的是相同的定义配置,那这些重复的字段就只需要配置一个,保证提交的字段名称遵守这个前缀、后缀即可。这就是动态字段。

    如:整型字段都是一样的定义,则可以定义一个动态字段如下:

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

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

    复制字段时,source 可以是动态字段。

    uniqueKey 唯一键

    指定用作唯一的字段,非必需。在删除文档的时候可以通过唯一键删除。

    #业务id
    <uniqueKey>id</uniqueKey>
    

    唯一键字段不可以是保留字段、复制字段,且不能分词。

    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>
    

    3、Schema API介绍

    Schema API

    Schema 操作API总体介绍

    Solr中强烈推荐使用 Schema API 来* 管理集合/内核* 的模式信息,可以 读、写 模式信息。通过API来更新模式信息,solr将 自动重载内核但是请注意:模式修改并不会自动重新索引已索引的文档,只会对后续的文档起作用,如果必要,你需要手动重新索引(删除原来的,重新提交文档)

    更新 Schema

    发送 post 请求 /collection/schema(/集合或内核的名字/schema),以JSON格式提交数据,在json中说明你要进行的更新操作及对应的数据(一次请求可进行多个操作)。

    • 更新操作定义
    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: 删除一个复制字段规则.
    

    V1、V2 两个版本API说明

    V1老版本的api,V2新版本的API,当前两个版本的API都支持,将来会统一到新版本。两个版本的API只是请求地址上的区别参数没区别

    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",  #根据名称来进行替换
         "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 动态字段操作

    • 添加一个动态字段 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
    
    • 删除一个动态字段 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
    
    • 替换一个动态字段 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 复制字段操作

    • 添加复制字段 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
    
    • 删除复制字段 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 /集合或者内核名称/schema
    

    可以通过 wt 请求参数指定返回的格式:json,xml,schema.xml

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

    请求参数

    • wt:json/xml

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

    • showDefaults:true/false ,是否返回字段的默认属性

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

    • 获取动态字段

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

    可用请求参数:wt、showDefaults

    http://localhost:8983/api/cores/mycore/schema/dynamicfields?wt=xml
    
    • 获取字段类别
    GET /collection/schema/fieldtypes
    GET /collection/schema/fieldtypes/name
    

    可用请求参数:wt、showDefaults

    http://localhost:8983/api/cores/mycore/schema/fieldtypes?wt=xml
    
    • 获取复制字段
    GET /collection/schema/copyfields
    

    可用请求参数:wt、source.fl、dest.fl

    • 获取其他信息
    GET /collection/schema/name        获取schema的name
    GET /collection/schema/version   获取schema的版本
    GET /collection/schema/uniquekey     获取唯一键字段
    GET /collection/schema/similarity    获取全局相关性计算类
    

    可用请求参数:wt

    相关文章

      网友评论

          本文标题:Solr索引详解

          本文链接:https://www.haomeiwen.com/subject/pstmeftx.html