如何轻松添加自定义评分脚本

how do add a custom scoring script in painless

这种语言一点也不痛... 零个例子和文档缺乏...

我正在尝试构建嵌入之间的自定义距离函数,我已经在 python:

中完成了
def my_norm(x,y):
    norm_embeddings = [sum(a * a) ** 0.5 for a in x]
    norm_target = sum(y * y) ** 0.5
    z = y-x
    norm_top = [sum(a * a) ** 0.5 for a in z]
    return norm_top / (norm_embeddings+norm_target)

其中 x 是 N*m 数组,y 是 m 向量

这是我在无痛中得到的结果,甚至不知道这是否有效...

def normalized_euclidean_dist(def x, def y){
  def norm_embeddings= new ArrayList();
  def norm_target = Math.pow((y*y).sum(), 0.5);
  def z = y-x;
  def norm_top=new ArrayList();
  for (a in x){
    norm_embeddings.add(Math.pow((a*a).sum(), 0.5))
  }
  for (a in z){
    norm_top.add(Math.pow((a*a).sum(), 0.5))
  }
  return norm_top/(norm_embeddings+norm_target)
}

如何在脚本中调用这个函数?

如果没有实际的 docs/index 映射,很难对其进行调试,但这是调用脚本排序的一般方法

GET some_index/_search
{
  "query": {
    "match_all": {}
  },
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "lang": "painless",
        "source": """
        float normalized_euclidean_dist(def x, def y){
          def norm_embeddings= new ArrayList();
          def norm_target = Math.pow((y*y).sum(), 0.5);
          def z = y-x;
          def norm_top=new ArrayList();
          for (a in x){
            norm_embeddings.add(Math.pow((a*a).sum(), 0.5));
          }
          for (a in z){
            norm_top.add(Math.pow((a*a).sum(), 0.5));
          }
          return norm_top/(norm_embeddings+norm_target);
        }
        
        return normalized_euclidean_dist(doc['x_field'], doc['y_field']);
        """
      },
      "order": "asc"
    }
  }
}

将'x_field'和'y_field'替换成实际的字段名,据我了解都是数组,如果不是,则需要添加doc['x_field'].value

现在排序脚本需要 return 一个数字作为结果,但我可能会遗漏您的脚本中的某些内容,但在我看来它试图划分一个数组购买一个数字/另一个数组,这不会工作所以那里也有工作要做

脚本排序文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#script-based-sorting