Lucene 最近基于此原始分支为 Lucene 9.0.0 添加了 HNSW 近似最近邻搜索 (ANN):https://issues.apache.org/jira/browse/LUCENE-9004 .
Lucene支持预过滤吗?例如,假设我们想要对 2020 年之后创建的文档进行矢量搜索。是否可以在同一矢量搜索请求中过滤这些文档?或者我们必须在返回 ANN 搜索结果后进行后置过滤吗?
我注意到这里的
query
方法下有一个成员acceptOrds:https://javadoc.io/doc/org.apache.lucene/lucene-core/latest/org/apache/lucene/util/hnsw/HnswGraph .html。可以用来过滤吗?
据我所知,他们没有,我想它正在酝酿中,但我想这需要时间。你应该研究一下 Pinecone,据我所知 Pinecone 的元数据过滤确实很领先。
原因是通过预过滤,您的搜索范围受到限制,这会过滤掉 HNSW 图中的节点,因此您无法再使用该图执行 ANN 搜索,它已被过滤器“破坏” 。因此搜索恢复为精确的 kNN 搜索 - 例如,它慢。
后过滤可以很快,因为您能够维护图形结构并执行 ANN 搜索,但随后您要对结果进行过滤。因此,如果你说我想要前 5 个最相似的结果,你最终可能会得到 4 个、2 个结果,或者在最坏的情况下得到 0 个结果。
Pinecone 引入了一种名为“单级过滤”的功能,它可以像预过滤一样保持准确性,并返回您请求的确切匹配数量,同时(通常)像后过滤一样提供速度提升。这样您就可以两全其美。
引用Elasticsearch中的向量搜索:设计背后的基本原理,这将是人们消费Lucene的kNN搜索最常见的方式:
通过拥有自己的与段关联的 HNSW 图,并且其中节点由文档 ID 索引,Lucene 可以就如何最好地预过滤矢量搜索做出有趣的决定:或者通过线性扫描与过滤器匹配的文档(如果有选择性) ,或者通过遍历图并仅考虑与过滤器匹配的节点作为 top-k 向量的候选节点。