文档索引

本文档描述了如何将文档添加到索引中。

组件

  • Document - 包含实际的文档及其字段。
  • RSAddDocumentCtx - 在对文档进行索引时使用的每个文档状态。索引完成后,该状态将被丢弃。
  • ForwardIndex - 包含文档中找到的词条。正向索引用于写入InvertedIndex
  • InvertedIndex - 一个索引,用于将词条映射到适用文档中的出现位置。

架构

索引过程从创建一个新的RSAddDocumentCtx并向其添加一个文档开始。在内部,这被分成几个步骤。

  1. 提交

    创建DocumentContext,并将其与来自输入的文档(按接收到的方式)相关联。提交过程还将执行一些初步缓存。

  2. 预处理

    提交文档后,将对其进行预处理。预处理对所有文档输入字段执行无状态处理。对于文本字段,这意味着对文档进行分词并创建正向索引。预处理器将把这些信息存储在AddDocumentCtx中的每个字段变量中。然后,在索引阶段的后期,将把此计算结果写入持久索引。

    如果文档足够大,预处理将在单独的线程中完成,这允许并发预处理,并避免阻塞其他线程。如果文档较小,预处理将在主线程中完成,避免了额外上下文切换的开销。SELF_EXC_THRESHOLD宏包含“足够大”的阈值。

    文档预处理完成后,将提交以进行索引。

  3. 索引

    索引本身包括提交预处理阶段的预计算结果。它在单个线程中完成,并以队列的形式进行。

    由于文档必须按其文档 ID 分配的确切顺序写入索引,并且由于索引过程也必须让位于其他潜在的索引过程,因此您可能会遇到文档 ID 以非顺序方式写入索引的情况。为了解决这个问题,必须明确定义文档的实际写入顺序。如果只有一个线程写入文档,那么该线程在写入时不需要担心乱序 ID。

    拥有单个后台线程还有助于在多个方面进行优化,正如稍后将看到的那样。基本思想是,当有大量文档排队等待索引线程时,索引线程可以将它们视为批处理命令,从而大大减少 GIL 的锁定/解锁次数以及打开和关闭词条键的次数。

  4. 跳过已索引的文档

    下面的阶段可能一次对多个文档进行操作。当文档完全索引时,它会被标记为已完成。当线程遍历队列时,它只对尚未标记为已完成的项执行处理/索引。

  5. 词条合并

    词条合并或正向索引合并是在队列中有多个文档时进行的。扫描队列中每个文档的正向索引,并在其位置构建一个更大的主正向索引。正向索引中的每个条目都包含对源文档的引用以及正常的偏移量/分数/频率信息。

    创建主正向索引可以避免对每个文档打开公共词条键多次。

    如果队列中只有一个文档,则不会创建主正向索引。

    请注意,主正向索引的内部类型实际上不是ForwardIndex

  6. 文档 ID 分配

    此时,GIL 被锁定,并且队列中的每个文档都被分配了一个文档 ID。分配在写入索引之前立即完成,以减少 GIL 锁定的次数;因此,GIL 只锁定一次,就在索引写入之前。

  7. 写入索引

    在 GIL 被锁定的情况下,任何挂起的索引数据都会被写入索引。这通常涉及打开一个或多个 Redis 键,并将计算后的数据写入/复制到这些键中。

    完成此操作后,将发送给定文档的回复,并将AddDocumentCtx释放。

RATE THIS PAGE
Back to top ↑