使用solrJ

时间:2018-08-07 09:53:28

标签: solr solrj in-place solr5

我正在尝试对文档进行就地更新。

Solr版本-5.5.2

Schema.xml-

<dynamicField name="store_*" type="int" indexed="false" stored="false" docValues="true"/>
<field name="_version_" type="long" indexed="false" stored="false" docValues="true" multiValued="false"/>

solrconfig.xml-

<updateHandler class="solr.DirectUpdateHandler2">
  <updateLog>
    <str name="dir">${solr.ulog.dir:}</str>
    <int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
  </updateLog>
</updateHandler>`

正在使用UpdateHandler-DirectUpdateHandler2

根据this文章,目标字段是未索引(indexed =“ false”),未存储(stored =“ false”),单值(multiValued =“ false”)数字docValues( docValues =“ true”)字段。

我仅使用updateHandler.addDoc(addUpdateCommand);添加文档,而使用-添加文档后不执行提交  solrClient.commit();

问题没有提交,文档没有反映。

如果我使用autoSoftCommit并仅添加文档,则更改将反映在索引中,但filterCache将被清除。

我的目标是在不清除filterCache的情况下实现就地更新。

这可以实现吗?

1 个答案:

答案 0 :(得分:3)

简短的回答:不,您不能在不清除Solr缓存的情况下为文档建立索引(部分或就地更新仍是索引)并使其可搜索(或看到更改)。

长答案:您可以为文档建立索引并使缓存保持填充状态(openSearcher = false),但是新索引的文档将不会出现在搜索结果中,除非您执行硬或软提交。要了解为什么您应该了解Solr / Lucene的工作原理,

  1. Lucene索引表示为一组段。此外,每个段本身都是自动包含的索引,每个段具有多个文件。最后,一旦写入磁盘,段几乎是不可变的。

  2. 每个Solr核心都有一个IndexSearcher实例来执行查询。 IndexSearcher具有创建时存在的所有段的静态视图。 此视图在IndexSearcher的生存期内不会更改,并且缓存属于IndexSearcher。

  3. 每当您提交一次提交时,就会创建一个新细分。此操作将创建一个新的IndexSearcher以反映新添加(或更新)的文档。在初始化新的IndexSearcher时,旧的SearchSearcher仍在处理请求。新的IndexSearcher完成后,旧的如果未注册(已销毁),则新的IndexSearcher开始为查询请求提供服务。

因此,由于它属于新的IndexSearcher,因此filterCache被清除。但是,您可以使用autoWarming:用旧缓存中的值预填充新缓存(请参阅solrconfig.xml中的autowarmCount)。 。请注意,因为预热会影响性能-基本上,新的IndexSearcher会使用旧IndexSearcher缓存中的键(查询)重新运行一定百分比(可配置)的过滤器查询-因为预热完成之前IndexSearcher尚未准备好。

请参阅:https://wiki.apache.org/solr/SolrCaching#autowarmCount

PS:由于上述原因,通常不建议对每个新文档/更新发布一次提交。最好依靠自动硬提交和软提交。