我正在尝试对文档进行就地更新。
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的情况下实现就地更新。
这可以实现吗?
答案 0 :(得分:3)
简短的回答:不,您不能在不清除Solr缓存的情况下为文档建立索引(部分或就地更新仍是索引)并使其可搜索(或看到更改)。
长答案:您可以为文档建立索引并使缓存保持填充状态(openSearcher = false),但是新索引的文档将不会出现在搜索结果中,除非您执行硬或软提交。要了解为什么您应该了解Solr / Lucene的工作原理,
Lucene索引表示为一组段。此外,每个段本身都是自动包含的索引,每个段具有多个文件。最后,一旦写入磁盘,段几乎是不可变的。
每个Solr核心都有一个IndexSearcher实例来执行查询。 IndexSearcher具有创建时存在的所有段的静态视图。 此视图在IndexSearcher的生存期内不会更改,并且缓存属于IndexSearcher。
每当您提交一次提交时,就会创建一个新细分。此操作将创建一个新的IndexSearcher以反映新添加(或更新)的文档。在初始化新的IndexSearcher时,旧的SearchSearcher仍在处理请求。新的IndexSearcher完成后,旧的如果未注册(已销毁),则新的IndexSearcher开始为查询请求提供服务。
因此,由于它属于新的IndexSearcher,因此filterCache被清除。但是,您可以使用autoWarming:用旧缓存中的值预填充新缓存(请参阅solrconfig.xml中的autowarmCount)。 。请注意,因为预热会影响性能-基本上,新的IndexSearcher会使用旧IndexSearcher缓存中的键(查询)重新运行一定百分比(可配置)的过滤器查询-因为预热完成之前IndexSearcher尚未准备好。
请参阅:https://wiki.apache.org/solr/SolrCaching#autowarmCount
PS:由于上述原因,通常不建议对每个新文档/更新发布一次提交。最好依靠自动硬提交和软提交。