11

我知道弹性搜索在计算查询检索到的文档的分数时会考虑字段的长度。字段越短,权重越高(请参阅字段长度规范)。

我喜欢这种行为:当我搜索时,iphoneiphone 6Crappy accessories for: iphone 5 iphone 5s iphone 6.

现在,我想尝试提升这个东西,假设我想加倍它的重要性。

我知道可以使用函数 score修改分数,我想我可以通过脚本 score实现我想要的。

我试图在分数中添加另一个字段长度规范,如下所示:

    {
     "query": {
       "function_score": {
         "boost_mode": "replace",
         "query": {...},
         "script_score": {
             "script": "_score + norm(doc)"
         }
       }
     }
   }

但是我失败了,收到了这个错误:[No parser for element [function_score]]

编辑:

我的第一个错误是我没有将函数得分包装在“查询”中。现在我编辑了上面的代码。我的新错误说

GroovyScriptExecutionException[MissingMethodException
[No signature of method: Script5.norm() is applicable for argument types:
(org.elasticsearch.search.lookup.DocLookup) values: 
[<org.elasticsearch.search.lookup.DocLookup@2c935f6f>]
Possible solutions: notify(), wait(), run(), run(), dump(), any()]]

编辑:我提供了第一个答案,但我希望有一个更好的答案

4

2 回答 2

10

看起来您可以使用类型token_count字段和field_value_factor函数 score来实现这一点。

所以,在字段映射中是这样的:

"name": { 
  "type": "string",
  "fields": {
    "length": { 
      "type":     "token_count",
      "analyzer": "standard"
    }
  }
}

这将使用字段中的令牌数。如果您想使用字符数,您可以将分析器更改为standard对每个字符进行标记的自定义分析器。

然后在查询中:

"function_score": {
  ...,
  "field_value_factor": {
    "field": "name.length",
    "modifier": "reciprocal"
  }
}
于 2016-01-12T02:42:45.953 回答
3

我有这样的作品。下面,我从分数中减去我感兴趣的字段的长度。

{
 "query": {
   "function_score": {
     "boost_mode": "replace",
     "query": {...},
     "script_score": {
         "script": "_score  - doc['<field_name>'].value.length()"
     }
   }
 }
}

然而,与旧分数相比,我无法控制我减去的这个数字的相对权重。这就是为什么我不接受我的答案:我会等待更好的答案。理想情况下,我希望有一种方法可以访问 中的字段长度规范函数script_score,或者获得等效的结果。

于 2015-08-17T23:15:41.727 回答