在他们的网站上关于knn检索,他们写了
在近似 kNN 搜索过程中应用过滤器,以确保返回 k 个匹配文档。这与后过滤方法形成对比,后过滤方法是在近似 kNN 搜索完成后应用过滤器。后过滤的缺点是,即使有足够的匹配文档,有时也会返回少于 k 个结果。
使用knn检索进行属性过滤的典型方式是在knn之前(先进行属性过滤,然后通过暴力计算向量相似度)或在knn之后(首先高效地进行knn检索,然后进行属性过滤) 。这两者都不是完美的。第一种方法速度慢,第二种方法召回率低。
那么Elasticsearch在knn检索期间是如何进行属性过滤的呢?
预过滤器和后过滤器:您可以选择适合您的用例的一种。
k
匹配文档。
k
结果。
num_candidates
值来提高速度,并且可以通过增加
num_candidates
来调整搜索相关性。这是搜索速度和相关性之间的权衡。预过滤
inside支持预过滤。它在 OR
和
lexical search
之间创建逻辑
kNN search
条件。后置过滤
outside 支持后过滤。它在 AND
和
lexical search
之间创建逻辑
kNN search
条件。
继续阅读更多详细信息和示例。分离的 kNN 搜索和词法搜索结果
#match query
#1 hits.
GET collection-with-embeddings/_search
{
"query": {
"match": {
"text": "GLOSSARY"
}
}
}
#kNN query
#908 hits
GET collection-with-embeddings/_search
{
"knn": {
"field": "text_embedding.predicted_value",
"query_vector_builder": {
"text_embedding": {
"model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
"model_text": "how do I cook my pasta?"
}
},
"k": 1000,
"num_candidates": 1000
},
"_source": [
"id",
"text"
]
}
* 预过滤(kNN 外部的词法过滤器)
#hits: 908
GET collection-with-embeddings/_search
{
"query": {
"term": {
"text": "GLOSSARY"
}
},
"knn": {
"field": "text_embedding.predicted_value",
"query_vector_builder": {
"text_embedding": {
"model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
"model_text": "how do I cook my pasta?"
}
},
"k": 1000,
"num_candidates": 1000
},
"_source": [
"id",
"text"
]
}
向量和词法匹配的组合方式是通过 析取(即逻辑或条件),其中每个的分数 文档是使用凸组合计算的,即加权和 正如我们之前看到的,它的向量和词汇分数。* 后过滤(kNN 内部的词法过滤器)https://opster.com/guides/elasticsearch/operations/elasticsearch-hybrid-search/#Hybrid-search-with-dense-models
#hits 1
GET collection-with-embeddings/_search
{
"knn": {
"field": "text_embedding.predicted_value",
"query_vector_builder": {
"text_embedding": {
"model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
"model_text": "how do I cook my pasta?"
}
},
"filter": {
"match": {
"text": "GLOSSARY"
}
},
"k": 1000,
"num_candidates": 1000
},
"_source": [
"id",
"text"
]
}