如何使用自定义处理程序/插件在Solr服务器端更新Solr文档

如何使用自定义处理程序/插件在Solr服务器端更新Solr文档,solr,solr4,Solr,Solr4,我有一个拥有数百万条记录的核心。 我想添加一个自定义处理程序,用于扫描现有文档并根据条件(例如年龄>12岁)更新其中一个字段。 我更喜欢在Solr服务器端执行此操作,以避免向客户端发送数百万文档。 我正在考虑编写一个solr插件,它将接收一个查询并更新查询文档上的一些字段(如“按查询删除”处理程序)。 我想知道是否有现有的解决方案或更好的替代方案。 我在网上搜索了一段时间,没有找到更新文档的Solr插件示例(我不需要扩展更新处理程序)。 我已经编写了一个插件,其中使用了以下代码,这些代码运行良好

我有一个拥有数百万条记录的核心。
我想添加一个自定义处理程序,用于扫描现有文档并根据条件(例如年龄>12岁)更新其中一个字段。
我更喜欢在Solr服务器端执行此操作,以避免向客户端发送数百万文档。
我正在考虑编写一个solr插件,它将接收一个查询并更新查询文档上的一些字段(如“按查询删除”处理程序)。
我想知道是否有现有的解决方案或更好的替代方案。
我在网上搜索了一段时间,没有找到更新文档的Solr插件示例(我不需要扩展更新处理程序)。
我已经编写了一个插件,其中使用了以下代码,这些代码运行良好,但速度不如我需要的快。
目前我有:

AddUpdateCommand addUpdateCommand = new AddUpdateCommand(solrQueryRequest); 
DocIterator iterator = docList.iterator(); 
SolrIndexSearcher indexReader = solrQueryRequest.getSearcher(); 
while (iterator.hasNext()) { 
   Document document = indexReader.doc(iterator.nextDoc()); 
   SolrInputDocument solrInputDocument = new SolrInputDocument(); 
   addUpdateCommand.clear(); 
   addUpdateCommand.solrDoc = solrInputDocument; 
   addUpdateCommand.solrDoc.setField("id", document.get("id")); 
   addUpdateCommand.solrDoc.setField("my_updated_field", new_value); 
   updateRequestProcessor.processAdd(addUpdateCommand); 
} 
但这非常昂贵,因为更新处理程序将再次获取我手头已有的文档。
是否有一种安全的方法来更新lucene文档并将其写回,同时考虑所有与Solr相关的代码,如缓存、额外的Solr逻辑等?
我正在考虑将其转换为SolrInputDocument,然后通过Solr添加文档,但我需要首先转换所有字段。
提前感谢,,
Avner

我不确定以下内容是否会提高性能,但我认为这可能会对您有所帮助

它的描述听起来与您正在搜索的内容非常相关

This EntityProcessor imports data from different Solr instances and cores. 
The data is retrieved based on a specified (filter) query. 
This EntityProcessor is useful in cases you want to copy your Solr index 
and slightly want to modify the data in the target index. 
In some cases Solr might be the only place were all data is available.
但是,我找不到现成的特性来嵌入您的逻辑。因此,您可能需要扩展以下类

链接到

你可能知道,但还有几点

1) 使整个进程利用所有可用的cpu内核。让它多线程

2) 使用最新版本的Solr

3) 在不同的机器上以最小的网络延迟试验两个Solr应用程序。这将是一个艰难的决定:

same machine, two processes VS two machines, more cores, but network overhead.
4) 以适用于您的用例和特定实现的方式进行调整

5) 更多的资源:和


希望能有帮助。尽管有这个答案,让我知道统计数据。我很好奇,你的信息可能会对以后的人有所帮助。

要指出将自定义逻辑放在哪里,我建议结合使用

ScriptTransformer允许在从数据导入源提取每个实体后计算它,在将新实体写入solr之前操作它并添加自定义字段值

示例data-config.xml可能如下所示


如您所见,您可以执行任何您喜欢的数据转换,并且可以用javascript表示。因此,这将是一个很好的点来表达您的逻辑和转换


你说一个限制可能是
age>12
。我将通过SolrEntityProcessor的
query
属性来处理这个问题。您可以编写
query=age:[*到12]
,以便更新时只读取最长12年的记录。

您可能已经知道这一点,但在Solr中,更新文档的行为实际上意味着用包含更改值的更新文档替换原始文档。处理更改的通常方法是从源系统推送到索引中,通常基于日期或其他指示;不以某种方式在本地更新索引。你能为你想做的事情提供更多的背景吗?我知道删除/添加内容。在我的场景中,数据只存在于Solr索引(计算字段)中。稍后,我需要为所有文档的字段添加一些数据,这些文档根据计算字段(在示例中为“年龄”字段)回答查询。在Solr端打开一个writer并更改文档有那么复杂吗?我没有遇到过这个确切的场景,但是假设更改值(以及后续更新)的“触发器”本身就是一个索引更新,那么这个链接可能会有帮助:感谢链接,但我的场景不同。我需要更改Solr core中的所有文档,而不仅仅是正在更新的文档。感谢您的推荐,我将查看您的指导并在得出最终结论(包括奖励)后进行更新@phaniThanks感谢您的推荐,我将查看您的指导,并在得出最终结论(包括奖励)后进行更新@切夫