sphinx的配置项有一项是:
sql_query_killlist
问题
假设我们有一个主索引main和一个增量索引delta,在主索引创建好后,每隔几分钟就重新创建增量索引(当然增量索引诗基于上一次的main索引创建的节点)。
我们假设在创建main索引的时候以上的文档(2,3,5,7, 11)中都包含"test",在过了一段时间后,增量索引中有一些文档,2,3,5文档被删除了, 7, 11文档被修改了,但11中已经不包含"test" 了。在这种情况下,我们在main中索引"test"的时候,会得到2,3,4,7,11, 在delta中索引"test"只能得到7了,而如果同时请求两个索引:
$sphinx->Query("test", "main delta");
这种情况下,我们的结果中应该不会出现2,3,5,11文档结果集。但实际上,结果中会包含11这个文档。
解析
这个文档是从main中得到的。即假如主索引和增量索引同时包含两个相同id的文档,但内容不一致,如果增量索引中找不到结果,sphinx就会尝试从主索引获取结果。
在这里,我们可以使用 sql_query_killlist来阻止这种问题.
sql_query_killlist会创建一个文档id列表,与某个索引项绑定在一起,用于隐藏从另一个索引中出现的结果,比如上面的2,3,5 和11,这个配置的实际意义也就在于处理已有的索引的删除和更新问题。
另外说明一下, 这个选项会依赖于请求中使用索引的顺序。(后面的索引项的killlist会隐藏与之冲突的前面的索引的文档)
解决
sql_query_killlist = \
SELECT id FROM documents WHERE updated_ts>=@last_reindex UNION \
SELECT id FROM documents_deleted WHERE deleted_ts>=@last_reindex
把这个写在delta的索引source下,就可以解决上面出现的问题了,即隐藏了在main中冲突的文档