脚本更新处理器
ScriptUpdateProcessorFactory 允许在 Solr 文档更新处理期间使用 Java 脚本引擎,从而在对文档进行索引之前灵活地表达自定义文档处理逻辑。
它具有对提交、删除、回滚等索引操作的钩子,但是添加是最常见的用法。它作为 UpdateProcessor 实现,以放置在 UpdateChain 中。
它以前称为 StatelessScriptingUpdateProcessor,已重命名以阐明此更新处理器的关键方面是启用脚本。 |
脚本可以用 JVM 支持的任何脚本语言(例如 JavaScript)编写,并动态执行,因此无需预编译。
能够在索引管道中运行您选择的脚本是一个非常强大的工具,我有时称之为免责卡,因为您可以通过这种方式解决一些无法通过其他方式解决的问题。但是,您正在引入一些潜在的安全漏洞。 |
模块
这是通过 scripting
Solr 模块 提供的,在使用之前需要启用它。
启用 ScriptingUpdateProcessor 和脚本引擎
Java 11 及更早版本附带一个名为 Nashorn 的 JavaScript 引擎,但 Java 12 将要求您添加自己的 JavaScript 引擎。其他受支持的脚本引擎(如 JRuby、Jython、Groovy)都要求您向 Solr 添加 JAR 文件。
详细了解如何将任何其他必需的 JAR 文件(取决于您的脚本引擎)添加到 Solr 的 Lib 目录 中。
配置
<updateRequestProcessorChain name="script">
<processor class="org.apache.solr.scripting.update.ScriptUpdateProcessorFactory">
<str name="script">update-script.js</str>
</processor>
<!-- optional parameters passed to script
<lst name="params">
<str name="config_param">example config parameter</str>
</lst>
-->
<processor class="solr.LogUpdateProcessorFactory" />
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
该处理器支持其配置的默认值/附加项/不变项概念。但是,也可以跳过此级别并在 <processor> 标记下直接配置参数。 |
以下是每个配置参数及其含义的列表
脚本
-
必需
默认值:无
脚本文件名。脚本文件必须放在
conf/
目录中。可以指定一个或多个“脚本”参数;多个脚本按指定顺序执行。 引擎
-
可选
默认值:无
可选择指定要使用的脚本引擎。仅当脚本文件的扩展名不是到脚本引擎的标准映射时才需要这样做。例如,如果你的脚本文件是用 JavaScript 编码的,但文件名被称为
update-script.foo
,请使用javascript
作为引擎名称。 params
-
可选
默认值:无
传递到脚本执行上下文的可选参数。这指定为具有嵌套类型参数的命名列表 (
<lst>
) 结构。如果指定,脚本上下文将获取一个“params”对象,否则将没有“params”对象可用。
脚本执行上下文
每个脚本都提供了一些变量。
logger
-
Logger (org.slf4j.Logger) 实例。这对于从脚本记录信息很有用。
req
-
SolrQueryRequest 实例。
rsp
params
-
从配置中指定的“params”对象(如果有)。
试用
“techproducts”配置集中有一个 JavaScript 示例 update-script.js
。
要试用脚本,请启用文件 ./server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
中的 <updateRequestProcessorChain name="script">
配置。然后通过 bin/solr start -e techproducts -Dsolr.modules=scripting
启动 Solr。
此 URL 演示指定“script”更新链:http://localhost:8983/solr/techproducts/update?commit=true&stream.contentType=text/csv&fieldnames=id,description&stream.body=1,foo&update.chain=script
,它记录以下内容
INFO: update-script#processAdd: id=1
你可以在 Solr 日志记录 UI 中看到记录的消息。
示例
processAdd()
和其他脚本方法可以返回 false 以跳过对文档的进一步处理。必须定义所有方法,尽管通常 processAdd()
方法是执行操作的地方。
Javascript
注意:检查 solrconfig.xml
并取消对更新请求处理器定义的注释以启用此功能。
function processAdd(cmd) {
doc = cmd.solrDoc; // org.apache.solr.common.SolrInputDocument
id = doc.getFieldValue("id");
logger.info("update-script#processAdd: id=" + id);
// Set a field value:
// doc.setField("foo_s", "whatever");
// Get a configuration parameter:
// config_param = params.get('config_param'); // "params" only exists if processor configured with <lst name="params">
// Get a request parameter:
// some_param = req.getParams().get("some_param")
// Add a field of field names that match a pattern:
// - Potentially useful to determine the fields/attributes represented in a result set, via faceting on field_name_ss
// field_names = doc.getFieldNames().toArray();
// for(i=0; i < field_names.length; i++) {
// field_name = field_names[i];
// if (/attr_.*/.test(field_name)) { doc.addField("attribute_ss", field_names[i]); }
// }
}
function processDelete(cmd) {
// no-op
}
function processMergeIndexes(cmd) {
// no-op
}
function processCommit(cmd) {
// no-op
}
function processRollback(cmd) {
// no-op
}
function finish() {
// no-op
}
Ruby
Ruby 支持是通过 JRuby 项目实现的。要将 JRuby 用作脚本引擎,请将 jruby.jar
添加到 Solr。
以下是一个 JRuby 更新处理脚本的示例(请注意,传递的所有变量都需要使用 $
前缀,例如 $logger
)
def processAdd(cmd)
doc = cmd.solrDoc # org.apache.solr.common.SolrInputDocument
id = doc.getFieldValue('id')
$logger.info "update-script#processAdd: id=#{id}"
doc.setField('source_s', 'ruby')
$logger.info "update-script#processAdd: config_param=#{$params.get('config_param')}"
end
def processDelete(cmd)
# no-op
end
def processMergeIndexes(cmd)
# no-op
end
def processCommit(cmd)
# no-op
end
def processRollback(cmd)
# no-op
end
def finish()
# no-op
end
Groovy
将 Groovy 发行版的 lib/
目录中的 JAR 添加到 Solr。可能不需要 Groovy 发行版中的所有 JAR,但不仅仅需要主 groovy.jar
文件(至少在使用 Groovy 2.0.6 测试时)
def processAdd(cmd) {
doc = cmd.solrDoc // org.apache.solr.common.SolrInputDocument
id = doc.getFieldValue('id')
logger.info "update-script#processAdd: id=" + id
doc.setField('source_s', 'groovy')
logger.info "update-script#processAdd: config_param=" + params.get('config_param')
logger.info "update-script#processAdd: request_param=" + req.params.get('request_param')
rsp.add('script_processed',id)
}
def processDelete(cmd) {
// no-op
}
def processMergeIndexes(cmd) {
// no-op
}
def processCommit(cmd) {
// no-op
}
def processRollback(cmd) {
// no-op
}
def finish() {
// no-op
}
Python
Python 支持是通过 Jython 项目实现的。将独立 jython.jar
(包含所有依赖项的 JAR)添加到 Solr 中。
def processAdd(cmd):
doc = cmd.solrDoc
id = doc.getFieldValue("id")
logger.info("update-script#processAdd: id=" + id)
def processDelete(cmd):
logger.info("update-script#processDelete")
def processMergeIndexes(cmd):
logger.info("update-script#processMergeIndexes")
def processCommit(cmd):
logger.info("update-script#processCommit")
def processRollback(cmd):
logger.info("update-script#processRollback")
def finish():
logger.info("update-script#finish")