【发布时间】:2021-04-17 11:11:38
【问题描述】:
我目前正在尝试对两个索引进行混合搜索:全文索引和 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) 的命中。
查询结构是否有错误?这可能是在映射方面吗?如果没有,有没有更好的方法?
感谢您的帮助!
【问题讨论】:
标签: python elasticsearch