1、Schema介绍
schema 是什么?
Schema:模式,是集合/内核中字段的定义,让solr知道集合/内核包含哪些字段、字段的数据类型、字段该索引的存储。
schema 的定义方式
solr中提供了两种方式来配置schema,两者只能选其一:
- 默认方式,通过Schema API 来实现配置,模式信息存储在 内核目录的conf/managed-schema文件中。
- 传统的手工编辑 conf/schema.xml的方式,编辑完后需要重载集合/内核才会生效。
schema 两种配置方式切换
- schema.xml 到 managed schema
只需要将 solrconfig.xml 中的
去掉,或改为 ManagedIndexSchemaFactory。
solr重启时,他发现存储 schema.xml 但不存储在 managed-schema,他会备份 schema.xml,然后改写 schema.xml 为 managed-schema。此后既可以通过schema API 管理schema了。
- managed schema 到 schema.xml
- 将 managed schema 重命名为 schema.xml
- 将 solrconfig.xml 中 schemaFactory 的 ManagedIndexSchemaFactory 去掉(如果存在)
- 增加
solr还支持无模式方式,solr会猜测该如何索引字段,不可用在生产环境下。
managed-schema文件构成
#字段
#动态字段
id #唯一key的指定
#拷贝字段
#字段存储类型
2、字段定义详解
字段定义示例
字段属性说明
name:字段名,必需。字段名可以由字母、数字、下划线构成,不能以数字开头。以下划线开头和结尾的名字为保留字段名,如 version
type:字段的 fieldType名,必需。为 FieldType 定义的name属性值。
default:默认值,如果提交的文档中没有该字段值,则自动会为文档添加这个默认值。非必需(indexed,stored,termVectors等属性)。
-
字段中用于覆盖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 字段类型,需要为其定义分析器。
#分析器
- 可以直接通过class属性指定分析器类,必须继承
org.apache.lucene.analysis.Analyzer
- 也可灵活地组合分词器、过滤器:
#分词器
#过滤器
org.apache.solr.analysis 包下的类可以简写为 solr.xxx
- 如果该类型字段索引、查询时需要使用不同的分析器,则需区分配置analyzer
#索引
#查询
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 停用此过滤器
#停用词过滤器
words属性指定停用词文件的绝对路径或相对 conf/ 目录的相对路径
停用词定义语法:一行一个
- Synonym Graph Filter 同义词过滤器
#同义词过滤器
#同义词过滤器
同义词定义语法:一类一行,=>表示标准化为后面的。
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适配类
时间字段类型特别说明
- 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 用于字段值是一个枚举集,且排序顺序可预订的情况,如新闻分类这样的字段,定义非常简单:
docValues="true" enumsConfig="enumsConfig.xml" enumName="priority"/>
- enumsConfig:指定枚举值的配置文件,绝对路径或相对 内核 conf/ 的相对路径
- enumName:指定配置文件的枚举名。排序顺序是按配置的排序。
- docValues:枚举类型字段必须设置 true。
枚举xml配置文件
Not Available
Low
Medium
High
Urgent
Unknown
Very Low
Low
Medium
High
Critical
# 创建一个新闻类别的枚举字段类别,枚举值:时事、财经、科技、体育、娱乐、教育、汽车
时事
财经
科技
体育
娱乐
教育
汽车
fileType调用新闻类枚举值:
dynamic Field 动态字段
问: 如果模式中有近百个字段需要定义,其中有很多字段的定义是相同,重复定义是不是很烦?
可不可以定一个规则,字段名以某前缀开头或结尾的是相同的定义配置,那这些重复的字段就只需要配置一个,保证提交的字段名称遵守这个前缀、后缀即可。这就是动态字段。
如:整型字段都是一样的定义,则可以定义一个动态字段如下:
#也可以是前缀,如:name="i_*"
CopyField 复制字段
复制字段允许将 一个或多个 字段的值填充到一个字段中。它的用途有两种:
1、将多个字段内容填充到一个字段,来进行搜索
2、对同一个字段内容进行不同的分词过滤,创建一个新的可搜索字段
定义方式:
1、先定义一个普通字段
2、定义复制字段
复制字段时,source 可以是动态字段。
uniqueKey 唯一键
指定用作唯一的字段,非必需。在删除文档的时候可以通过唯一键删除。
#业务id
id
唯一键字段不可以是保留字段、复制字段,且不能分词。
Similarity 相关性计算类配置
如果默认的相关性计算模型 BM25Similarity 不满足你应用的特殊需求,你可在schema中指定全局的字段类型局部相关性计算类。
text_dfr
I(F)
B
H3
900
3、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