在没有索引的情况下使用 whoosh 作为匹配器

Using whoosh as matcher without an index

是否可以在不建立索引的情况下使用 whoosh 作为匹配器?

我的情况是我有预定义的字符串订阅和流中的文档。我检查每个文档是否与订阅相匹配,如果是,就发送它们。我不需要存储文件,也不需要以后再调用它们。一旦它们被发送到订阅,它们就可以被丢弃。

目前仅使用简单匹配,但随着消费者要求基于字段、and/or 逻辑等进行搜索,我想知道是否可以使用 whoosh 匹配器并为此允许 whoosh 查询语法。

我可以为每个文档建立一个索引,查询它,然后扔掉,但是这样看起来很浪费,可不可以直接建立一个Matcher?我在网上找不到任何指示执行此操作的方法的文档或问题,而且我的尝试没有奏效。 或者,对于这项任务来说,这只是错误的库吗?有没有更适合的库?

简短的回答是否定的。

搜索索引和匹配器的工作方式完全不同。例如,如果搜索短语“hello world”,匹配器将简单地检查文档文本是否包含子字符串“hello world”。搜索索引无法做到这一点,它必须检查每个文档,而且速度非常慢。

添加文档时,其中的每个词都会添加到该词的索引中。所以“hello”的索引会说文档 1 在位置 0 匹配,而“world”的索引会说文档 1 在位置 6 匹配。搜索“hello world”会在“ hello”索引,然后全部在“world”索引中,看看是否有“world”在“hello”位置后6位的位置。

所以这是一种完全正交的做事方式 whoosh 与 matcher。

可以使用 whoosh 来执行此操作,为每个文档使用一个新索引,如下所示:

def matches_subscription(doc: Document, q: Query) -> bool:
    with RamStorage() as store:
        ix = store.create_index(schema)
        writer = ix.writer()
        writer.add_document(
            title=doc.title,
            description=doc.description,
            keywords=doc.keywords
        )
        writer.commit()
        with ix.searcher() as searcher:
            results = searcher.search(q)
            return bool(results)

每次检查大约需要 800 毫秒,相当慢。

更好的解决方案是使用 pyparsing 构建解析器,然后创建您自己的嵌套查询 类,它可以进行匹配,更好地适合您的特定搜索查询。这样也很容易扩展。这可以将其降低到约 40 微秒,因此,速度提高了 20,000 倍。