【问题标题】:Function score query with field_value_factor on not (yet) existing field在不(尚)存在的字段上使用 field_value_factor 的函数得分查询
【发布时间】:2015-02-01 03:57:12
【问题描述】:

我已经在这个问题上搞砸了很长一段时间,无法解决这个问题。

举个例子:

我的公司有 2 名员工,他们有自己的博客页面:

POST blog/page/1
{
  "author": "Byron",
  "author-title": "Junior Software Developer",
  "content" : "My amazing bio"
}

POST blog/page/2
{
  "author": "Jason",
  "author-title": "Senior Software Developer",
  "content" : "My amazing bio is better"
}

在他们创建博客帖子后,我们希望跟踪他们博客的“浏览量”,并根据他们的“浏览量”提升搜索结果。

这可以通过使用function score query:来完成

GET blog/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "author-title": "developer"
        }
      },
      "functions": [
        {
          "filter": {
            "range": {
              "views": {
                "from": 1
              }
            }
          }, 
          "field_value_factor": {
            "field": "views"
          }
        }
      ]
    }
  }
}

我使用范围过滤器来确保 field_value_factor 在观看次数为 0 时不会影响得分(得分也会为 0)。

现在当我尝试运行这个查询时,我会得到以下异常:

nested: ElasticsearchException[Unable to find a field mapper for field [views]]; }]

这是有道理的,因为该字段在索引中的任何位置都不存在。 如果我要在索引时间添加views = 0,我不会遇到上述问题,因为该字段在索引中是已知的。但在我的用例中,我无法在索引时间或映射中添加它。

基于在函数分数查询中使用范围过滤器的能力,我认为我可以使用exists filter 来确保 field_value_factor 部分仅在该字段实际存在于索引中时才被执行,但没有这样的运气:

GET blog/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "author-title": "developer"
        }
      },
      "functions": [
        {
          "filter": {
            "bool": {
              "must": [
                {
                  "exists": {
                    "field": "views"
                  }
                },
                {
                  "range": {
                    "views": {
                      "from": 1
                    }
                  }
                }
              ]
            }
          },
          "field_value_factor": {
            "field": "views"
          }
        }
      ]
    }
  }
}

仍然给出:

nested: ElasticsearchException[Unable to find a field mapper for field [views]]; }]

我希望 Elasticsearch 在解析 field_value_factor 之前先应用过滤器。

关于如何在不使用映射文件或在索引时间或脚本期间修复的情况下解决此问题有什么想法吗??

【问题讨论】:

标签: java elasticsearch scoring


【解决方案1】:

您看到的错误发生在查询解析时,即尚未执行任何操作。当时FieldValueFactorFunctionParser构建了稍后执行的filter_value_factor函数,但注意到映射类型中不存在views字段。

注意过滤器还没有被执行,就像filter_value_factor函数一样,它只被FunctionScoreQueryParser解析。

我想知道为什么你不能简单地在你的映射类型中添加一个字段,它就像运行这个一样简单

curl -XPUT 'http://localhost:9200/blog/_mapping/page' -d '{
    "page" : {
        "properties" : {
            "views" : {"type" : "integer"}
        }
    }
}'

如果这真的不是一个选项,另一种可能性是使用script_score,如下所示:

{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "author-title": "developer"
        }
      },
      "functions": [
        {
          "filter": {
            "range": {
              "views": {
                "from": 1
              }
            }
          }, 
          "script_score": {
            "script": "_score * doc.views.value"
          }
        }
      ]
    }
  }
}

【讨论】:

    猜你喜欢
    • 2019-09-03
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2016-01-24
    相关资源
    最近更新 更多