Solr中如何通过正则替换DateField等非TextField字段的索引值
可行实现方案
非TextField类型的Solr内置字段(包括TrieDateField、各类数值字段)本身不支持自定义分词、CharFilter这类文本分析配置,你写在<analyzer>标签里的规则不会被加载生效,不用在这个方向上耗时间。生产环境用「存储字段+索引字段分离+更新链预处理」的方案就能完全满足需求,不需要改源码,也不影响日期运算能力。
具体实现步骤
- 拆分两个独立字段,分别承担存储和索引职责
- 原始值存储字段:用
string类型(StrField),配置stored="true" indexed="false",专门存birthday|2000-01-01T00:00:00Z这类完整原始值,不参与任何索引和查询,只在结果返回时输出原始内容 - 日期索引字段:用原生日期类型(高版本Solr用
pdate即DatePointField,老版本用TrieDateField就行),配置stored="false" indexed="true" multiValued="true",专门存截掉前缀的纯日期值,所有日期范围查询、日期函数运算、时间聚合都走这个字段,完全兼容原生日期类型的所有查询能力
- 原始值存储字段:用
- 配置Solr自带的更新请求处理器链,在文档写入阶段自动完成值拆分,不需要业务端提前处理数据
- 先把输入的原始值完整复制到存储字段留存
- 用正则替换处理器把输入值里
|前缀的部分删掉,得到纯ISO格式日期 - 把处理完的纯日期值复制到日期索引字段用于检索
配置示例
字段定义
<!-- 原始值存储字段:只存不索引 --> <field name="custom_dates_raw" type="string" multiValued="true" stored="true" indexed="false"/> <!-- 日期索引字段:只索引不存,用于日期检索运算 --> <field name="custom_dates_index" type="pdate" multiValued="true" stored="false" indexed="true"/>
更新链配置
把下面的配置加到solrconfig.xml里,写入文档时指定使用这个更新链即可自动完成值拆分:
<updateRequestProcessorChain name="dateSplitChain"> <!-- 备份原始值到存储字段 --> <processor class="solr.CloneFieldUpdateProcessorFactory"> <str name="source">custom_dates</str> <str name="dest">custom_dates_raw</str> </processor> <!-- 正则截掉|前的前缀,得到纯日期字符串 --> <processor class="solr.RegexReplaceProcessorFactory"> <str name="fieldName">custom_dates</str> <str name="pattern">^.*?\|(.*)$</str> <str name="replacement">$1</str> </processor> <!-- 处理后的纯日期值写入索引字段 --> <processor class="solr.CloneFieldUpdateProcessorFactory"> <str name="source">custom_dates</str> <str name="dest">custom_dates_index</str> </processor> <!-- 清理临时输入字段,不需要可以删除这步 --> <processor class="solr.RemoveFieldUpdateProcessorFactory"> <str name="fieldName">custom_dates</str> </processor> <processor class="solr.LogUpdateProcessorFactory"/> <processor class="solr.DistributedUpdateProcessorFactory"/> <processor class="solr.RunUpdateProcessorFactory"/> </updateRequestProcessorChain>
其他可选方案
如果必须用单字段实现,可以自己写Java代码自定义字段类型,继承对应的原生日期字段类,重写索引阶段的值解析逻辑,在解析前加正则替换步骤,打包成jar放到Solr的lib目录加载即可。但这个方案需要自己维护自定义组件代码,版本升级兼容性差,没有特殊需求不推荐用。
注意:Solr所有非文本的点类型字段(日期、数值、地理坐标等)的分析逻辑是硬编码实现的,无论怎么配置
<analyzer>下的tokenizer、charFilter都不会生效,不用尝试这类配置。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

