代码之家  ›  专栏  ›  技术社区  ›  mP.

如何合并来自两个不同(非分片)lucene索引的匹配项

  •  5
  • mP.  · 技术社区  · 15 年前

    我有两个单独的索引,包含不同的字段,这些字段一起包含索引的所有可搜索字段。例如,第一个索引保存所有文档的索引文本,第二个索引保存每个文档的标记。

    注意下面的例子有点奇怪,因为我已经更改了实体的名称。 索引1: 文本 文档ID

    索引2: 标签名称:“非常重要” 用户:“弗雷德的身份证”

    我想将索引分开,因为每当用户添加/删除标记时,不断更新单个索引似乎很浪费。

    到目前为止,我认为我可能需要处理这两个搜索结果并手动合并它们(在代码中)。还有其他建议吗?

    我不想合并单独/分片索引。

    3 回复  |  直到 15 年前
        1
  •  4
  •   erickson    15 年前

    Lucene有一种 IndexReader 支持这种安排- ParallelReader .

    这可能有点棘手,因为记录中的Lucene文档标识符必须在两个索引中都相同。实际上,这意味着向两个索引添加相同顺序的文档。我已经读到,在某些情况下,文档删除和索引优化可以导致Lucene重新分配这些文档标识符,但我还没有尝试去验证这是否是真的。如果修改了现有记录,可能需要格外小心。如果只追加新记录,就不会有麻烦。

    这种方法通常称为“垂直分区”,而不是“水平分区”或分片。

        2
  •  0
  •   Yuval F    15 年前

    似乎需要在代码中合并索引。如果我理解正确,当搜索一个术语时,可以有匹配文本或标签的匹配,并且每个标签都用其相关的文档ID来索引。然后您将有两个要合并的命中列表。由于标签和全文是非常不同的实体,您将需要一些权重(可能在检索期间字段增加)来达到良好的排名。因此,您可以使用类似的公式将文档命中和全文命中合并为:

    score(k) = a*tagscore(k)+b*fulltextscore(k)

    其中a和b是经验确定的系数。

    有关更详细的讨论,请参见Grant Ingersoll的 findability debugging relevance issues in search 论文。

        3
  •  0
  •   jeremyalan    15 年前

    这种方法的主要问题与文档的排序有关,因为默认算法(可能是大多数自定义算法,只有少数例外)基于术语频率和文档反频率。

    换句话说,记分员需要知道一个术语在文档中出现的次数,以及包含该术语的其他文档的数量。此信息是为索引中的每个术语存储的,但不是跨多个索引的聚合。

    解决这一问题的共同办法是分两个阶段进行。首先,对每个索引运行查询,以确定每个词包含多少文档。接下来,将聚合结果并再次运行查询,但这次将同时发送相反的文档频率。

    正如你可以想象的那样,这将无法运行对单个索引的查询,但是由于没有什么是免费的,所以我认为这是将文档存储在多个索引之间的折衷。