【问题标题】:Elasticsearch Hybrid Query - Always returning a score of 0Elasticsearch 混合查询 - 始终返回 0 分
【发布时间】: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


    【解决方案1】:

    当解决方案不允许在运行 k-NN 之前进行预过滤并且需要在过滤器之前运行 k-NN 时,我看到了类似的问题。这通常会导致空集结果,因为初始 k-NN 中的所有命中均未与后续过滤器对齐。

    这是一个可能有帮助的选项,因为它允许在 k-NN 之前进行预过滤:https://medium.com/gsi-technology/scalable-semantic-vector-search-with-elasticsearch-e79f9145ba8e

    【讨论】:

      【解决方案2】:

      现在,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"
                      }
                  }
              }
          }
      }
      

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
      猜你喜欢
      • 2023-03-14
      • 1970-01-01
      • 2021-03-13
      • 2021-08-07
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多