Elasticsearch最佳匹配排序机制,通过计算突出显示和数组中元素的数量

ar7v8xwq  于 2023-10-17  发布在  ElasticSearch
关注(0)|答案(1)|浏览(96)

我正在使用ElasticSearch 7.6,我试图找出一种方法来根据搜索查询的最佳匹配对结果进行排序。
这有两个部分,我将尝试解释,但首先我将提供一个数据Map的演示结构:

"handles" : {
      "properties" : {
        "references" : {
        },
        "value" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
    },

所以我们有handles,我们还有4个属性与handles具有相同的Map,它们是:summarycontact_detailsmotivesinterests
系统必须在handles.value.keyword等上搜索其余属性。
现在有两种类型的最佳匹配机制:

产品目录

目录是当你访问页面时,你还没有搜索任何东西,系统将在没有搜索查询的情况下获取最佳匹配结果,这是策略:
5个可用属性中的任何属性在数组中至少包含1个元素,都会将分数增加1:
这个例子仅适用于handle,以防止这篇文章太长:

"query": {

    "function_score": {
      "query": {
        "bool": {
          "must": [
          ]
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
              "source": """
                double score = 0;
                if (doc['handles.value.keyword'].size() > 0) { 
                  score += 1;
                
                }
                return score;
              """
            }
          }
        }
      ],
      "boost_mode": "max"
    }
  },

这工作完美。
但我的问题是第二种机制。

查询最佳匹配

现在,当你插入一个查询时,当每个属性在数组中至少有一个元素时,我仍然会增加分数,但我也想在每次突出显示5个属性中的任何一个元素时(完全匹配或完全匹配)增加分数。
例如,如果我找到3个匹配项:
1.handles.value['ben', 'ben10', 'car']兴趣.值['ben']
1.handles.value['car', 'ben', 'ten']
1.handles.value['car', 'ben']兴趣.value['ben']
我的搜索查询是ben*,最佳匹配排序将是:
1, 3, 2
由于1包含3个高光,它将是第一个,第3个包含2个高光,它将被排序为第二个,第2个将是第3个,因为它包含一个高光。
“那又怎么样?”**弹性排序函数没有返回的突出显示的上下文,所以我不知道什么值是完全匹配的,所以我不能真正计数。也许我可以遍历脚本中的所有元素,并检查元素中是否包含查询字符串,但这可能非常不稳定,因为我有超过200万个项目,甚至可能更多。
举例说明:

for(handle in doc['handles.value.keyword'])
          {
            if(handle.value.toString().contains('ben'))
            {
              score += 2;
            }
          }

在elasticsearch中有没有合适的方法来实现这样的评分机制?

kuarbcqp

kuarbcqp1#

第一部分(目录)不需要任何脚本。它可以通过在布尔查询中使用简单的exist查询来完成。第二部分比较棘手。大多数处理搜索结果的查询不计算匹配项的数量。但是,如果你总是在搜索中使用前缀,像match_phrase_prefix这样的自定义相似度可能会起作用。

DELETE test

PUT test
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 1,
    "similarity": {
      "scripted_tf": {
        "type": "scripted",
        "script": {
          "source": "doc.freq"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "handles" : {
        "properties" : {
          "value": {
            "type": "text",
            "similarity": "scripted_tf",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          }
        }
      },
      "interests" : {
        "properties" : {
          "value": {
            "type": "text",
            "similarity": "scripted_tf",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          }
        }
      }
    }
  }
}

POST test/_bulk?refresh
{"index":{"_id":1}}
{"handles.value":["ben","ben10","car"],"interests.value":["ben"]}
{"index":{"_id":2}}
{"handles.value":["car","ben","ten"]}
{"index":{"_id":3}}
{"handles.value":["car","ben"],"interests.value":["ben"]}

// Catalog Query
GET test/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "exists": {
            "field": "handles.value"
          }
        },
        {
          "exists": {
            "field": "interests.value"
          }
        }
      ]
    }
  }
}

// Best match based on query

GET test/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "exists": {
            "field": "handles.value"
          }
        },
        {
          "exists": {
            "field": "interests.value"
          }
        },
        {
          "match_phrase_prefix": {
            "handles.value": {
              "query": "ben"
            }
          }
        },
        {
          "match_phrase_prefix": {
            "interests.value": {
              "query": "ben"
            }
          }
        }
      ]
    }
  }
}

如果您能够阐明您期望用户键入的内容,我可能能够调整此示例以更好地匹配您的用例。

相关问题