elasticsearch - 仅调整某些查询的相关性分数
问题描述
我有一个用例,当用户根据术语搜索某些搜索词时,我需要从该搜索词的总结果中对某些文档进行排名。
到目前为止我已经尝试过:
我已经tuning
在索引上的文档中添加了一个嵌套字段,它将具有这些自定义提升。
{
_id: 1234,
'name': 'Fancy potato masher',
'tuning': [
{'term': 'potato', 'rank': 5},
{'term': 'masher', 'rank': 10},
]
},
{
_id: 2345,
'name': 'Decent potato masher',
'tuning': [
{'term': 'potato', 'rank': 3},
{'term': 'masher', 'rank': 7},
]
},
{
_id: 3456,
'name': 'Useless potato masher',
'tuning': [
{'term': 'potato', 'rank': -5},
{'term': 'masher', 'rank': -7},
]
},
{
_id: 4567,
'name': 'Ordinary potato masher',
'tuning': []
}
所以在这里当我们搜索potato
or时masher
,我希望结果的顺序是1234, 2345, 4567, 3456
。
我sort
的部分查询如下所示:
{
'sort': {
'tuning.rank' => {
'order' => 'desc',
'nested' => {
'path' => 'tuning',
'filter' => {
'match' => {
'tuning.term' => 'potato'
}
}
}
},
}
}
我的结果是有序的1234, 2345, 3456, 4567
。所以基本上任何缺少tuning
数据的东西都会出现在最后,而不是那些有负数的。
这个问题如何在不花哨的学习排名等的情况下正常解决。
解决方案
只需添加missing
参数,如下例所示。
另请注意,您使用的方式nested_filter
已nested_path
被弃用,如ES 6.2版本后的此链接中所述。
我已经提到了如何使用最新和不推荐使用的 DSL 来获得你想要的东西。根据您使用的版本随意使用。
查询 pre ES 6.2 版本
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {} //query logic as per your requirement
}
]
}
},
"sort": [
{
"tuning.rank": {
"order": "desc",
"nested_path": "tuning",
"nested_filter": {
"match": {
"tuning.term": "potato"
}
},
"missing": "0" <------ Note this.
}
}
]
}
在上面的查询中,只关注排序逻辑,我刚刚添加missing
了带有值的参数,0
这意味着如果字段tuning.term
丢失,让排序值成为0
文档将相应地排序。
查询 ES 6.2+ 版本
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
]
}
},
"sort":[
{
"tuning.rank":{
"order": "desc",
"nested":{
"path": "tuning",
"filter":{
"match":{
"tuning.term": "potato"
}
}
},
"missing": "0"
}
}
]
}
以下是响应在我的机器中的显示方式:
回复:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "1234",
"_score" : null,
"_source" : {
"name" : "Fancy potato masher",
"tuning" : [
{
"term" : "potato",
"rank" : 5
},
{
"term" : "masher",
"rank" : 10
}
]
},
"sort" : [
5
]
},
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "2345",
"_score" : null,
"_source" : {
"name" : "Decent potato masher",
"tuning" : [
{
"term" : "potato",
"rank" : 3
},
{
"term" : "masher",
"rank" : 7
}
]
},
"sort" : [
3
]
},
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "4567",
"_score" : null,
"_source" : {
"name" : "Ordinary potato masher",
"tuning" : [ ]
},
"sort" : [
0
]
},
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "3456",
"_score" : null,
"_source" : {
"name" : "Fancy potato masher",
"tuning" : [
{
"term" : "potato",
"rank" : -5
},
{
"term" : "masher",
"rank" : -7
}
]
},
"sort" : [
-5
]
}
]
}
}
现在,如果您运行查询,您的结果将被相应地排序。
更新的相关性答案:
您在上面看到我正在使用自定义排序,就此而言,相关性不会出现。
默认情况下,如果您不使用任何排序逻辑,则结果按相关性排序,您将能够查看_score
值。
另请注意,我使用的是 match_all,它会给每个文档打 1 分。因此,如果您删除排序逻辑,您将在我共享的查询中返回所有得分为 1 的文档。
相关性是一个复杂的主题,它在很大程度上取决于您的用例。我建议您花一些时间研究function_score查询,以便您了解如何影响分数。稍微玩一下,你就会慢慢开始理解它是如何工作的。
至于您的评论,如果您还想显示或显示_score
,您只需在排序逻辑中添加 _score 字段。所以首先,它会对文档进行排序,tuning.rank
然后它会根据_score
.
下面是它是如何完成的。
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
]
}
},
"sort":[
{
"tuning.rank":{
"order": "desc",
"nested":{
"path": "tuning",
"filter":{
"match":{
"tuning.term": "potato"
}
}
},
"missing": "0"
}
},
{
"_score": { "order": "desc" }
}
]
}
回复:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "1234",
"_score" : 1.0,
"_source" : {
"name" : "Fancy potato masher",
"tuning" : [
{
"term" : "potato",
"rank" : 5
},
{
"term" : "masher",
"rank" : 10
}
]
},
"sort" : [
5,
1.0
]
},
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "2345",
"_score" : 1.0,
"_source" : {
"name" : "Decent potato masher",
"tuning" : [
{
"term" : "potato",
"rank" : 3
},
{
"term" : "masher",
"rank" : 7
}
]
},
"sort" : [
3,
1.0
]
},
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "4567",
"_score" : 1.0,
"_source" : {
"name" : "Ordinary potato masher",
"tuning" : [ ]
},
"sort" : [
0,
1.0
]
},
{
"_index" : "someindex",
"_type" : "_doc",
"_id" : "3456",
"_score" : 1.0,
"_source" : {
"name" : "Fancy potato masher",
"tuning" : [
{
"term" : "potato",
"rank" : -5
},
{
"term" : "masher",
"rank" : -7
}
]
},
"sort" : [
-5,
1.0
]
}
]
}
}
此外,为了让您可以看到相关性文档不是按相关性排序而是基于您的排序逻辑,请尝试运行以下查询:
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "potato decent"
}
}
]
}
},
"sort":[
{
"tuning.rank":{
"order": "desc",
"nested":{
"path": "tuning",
"filter":{
"match":{
"tuning.term": "potato"
}
}
},
"missing": "0"
}
},
{
"_score": { "order": "desc" }
}
]
}
您可以在结果中看到,具有较高 _score 值的文档仍然会出现在较低的位置,因为我们主要基于tuning.rank
.
希望能帮助到你!
推荐阅读
- node.js - 无法处理 alexa 意图
- c# - 在 C# 中构造 SQL 查询时是否可以使用两个不同的实体?
- javascript - 材质ui SingleExpand TreeView 属性?
- visual-studio-code - 如何解决 Visual Studio 代码中 C# 脚本 csx 文件的依赖问题?
- python - 如何使用 matplotlib 在数据框中绘制对象的值?
- r - 计算R中每组有多少人
- java - 错误在同一包中找不到具有接口的符号
- c++ - 在 Qt 桌面应用程序上运行 Selenium
- c++ - 在 C++17 中在对象的生命周期之外调用非静态成员函数
- python - 尽管在基类中定义了属性,但 PyCharm 在使用 __subclasses__() 时会警告“未解析的属性引用”