目录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)
感谢阅读, 若是文章有帮助或启发到你, 点个[好文要顶👆] 或 [推荐👍] 吧😜
本文版权归博主全部, 欢迎转载, 但 [必须在文章页面明显位置标明原文连接], 不然博主保留追究相关人员法律责任的权利.