python - Elasticsearch 混合查询 - 始终返回 0 分
问题描述
我目前正在尝试对两个索引进行混合搜索:全文索引和 knn_vector(词嵌入)索引。目前,来自 Wikipedia 的超过 10,000 个文档在 ES 堆栈上被索引,并在这两个字段上都被索引(参见映射:“内容”、“嵌入”)。查询是众所周知的 n-gram (1,2,3),应该会产生结果(单词取自被索引的维基百科页面)。
同样重要的是要注意 knn_vector 索引被定义为嵌套对象。
这是索引项目的当前映射:
mapping = {
"settings": {
"index": {
"knn": True,
"knn.space_type": "cosinesimil"
}
},
"mappings": {
"dynamic": 'strict',
"properties": {
"elasticId":
{ 'type': 'text' },
"owners":
{ 'type': 'text' },
"type":
{ 'type': 'keyword' },
"accessLink":
{ 'type': 'keyword' },
"content":
{ 'type': 'text'},
"embeddings": {
'type': 'nested',
"properties": {
"vector": {
"type": "knn_vector",
"dimension": VECTOR_DIM,
},
},
},
}
我的目标是比较两个索引上的查询分数,以了解一个是否比另一个更有效(全文与 knn_vectors),以及弹性如何根据每个索引的分数选择返回对象。
我知道我可以简单地拆分查询(两个单独的查询),但理想情况下,我们可能希望在生产中使用这种类型的混合搜索。
这是同时搜索全文和 knn_vectors的当前查询:
def MakeHybridSearch(query):
query_vector = convert_to_embeddings(query)
result = elastic.search({
"explain": True,
"profile": True,
"size": 2,
"query": {
"function_score": { #function_score
"functions": [
{
"filter": {
"match": {
"text": {
"query": query,
'boost': "5",
},
},
},
"weight": 2
},
{
"filter": {
'script': {
'source': 'knn_score',
'params': {
'field': 'doc_vector',
'vector': query_vector,
'space_type': "l2"
}
}
},
"weight": 4
}
],
"max_boost": 5,
"score_mode": "replace",
"boost_mode": "multiply",
"min_score": 5
}
}
}, index='files_en', size=1000)
当前的问题是所有查询都没有返回任何内容。 结果:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
},
即使查询确实返回了响应,它也会返回得分为 0 (score =0) 的命中。
查询结构是否有错误?这可能是在映射方面吗?如果没有,有没有更好的方法来做到这一点?
谢谢您的帮助 !
解决方案
现在,aws elasticsearch 支持后过滤。
https://docs.aws.amazon.com/opensearch-service/latest/developerguide/knn.html
页面中的示例查询是
{
"size": 2,
"query": {
"knn": {
"my_vector2": {"vector": [2, 3, 5, 6], "k": 2}
}
},
"post_filter": {
"range": {
"price": {"gte": 6, "lte": 10}
}
}
}
aws elasticsearch 还支持使用“script_score”进行预过滤(但它与原始 elasticsearch 中的“script_score”不同)
https://opendistro.github.io/for-elasticsearch-docs/docs/knn/knn-score-script/
页面中的示例查询是
{
"size": 2,
"query": {
"script_score": {
"query": {
"bool": {
"filter": {
"term": {
"color": "BLUE"
}
}
}
},
"script": {
"lang": "knn",
"source": "knn_score",
"params": {
"field": "my_binary",
"query_value": "U29tZXRoaW5nIEltIGxvb2tpbmcgZm9y",
"space_type": "hammingbit"
}
}
}
}
}
推荐阅读
- snowflake-cloud-data-platform - snowflake snowsql 错误 250003 (n/a): 未能执行请求: HTTPSConnectionPool(host='https 未能建立新连接
- vue.js - 为什么 Vuex 动作类型未知?
- ios - iOS 应用的 Firebase 不安全/公共端点
- c++ - 如何解决 make: None: Command not found 问题?
- windows - 使 HTML 不适用于 Windows 10 中的 Sphinx 文档
- python - 如何在 pytorch-lightning 中正确使用 Tensorboard 的 TSNE?
- javascript - 如何将 Firestore 文档中的所有数据显示到 html 表中
- c# - 使用 MasterDetailPage 导航到下一个详细信息页面时出现问题?
- android - 在 Navcontroller 中,我遇到了 getViewModelStoreOwner 未解决的问题
- vue.js - buefy通知中的自定义按钮