我已经在这个问题上搞砸了很长一段时间了,而且无法解决这个问题。
采取以下案例:
我公司有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"
}
在他们创建博客帖子之后,我们希望跟踪他们的观看次数'他们的博客并根据他们的观点提升搜索结果。
来完成GET blog/_search
{
"query": {
"function_score": {
"query": {
"match": {
"author-title": "developer"
}
},
"functions": [
{
"filter": {
"range": {
"views": {
"from": 1
}
}
},
"field_value_factor": {
"field": "views"
}
}
]
}
}
}
我使用范围过滤器确保当视图数量为0(得分也为0)时field_value_factor不会影响得分。
现在,当我尝试运行此查询时,我将得到以下异常:
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]]; }]
在解析field_value_factor之前,我希望Elasticsearch首先应用过滤器。
有关如何解决此问题的任何想法,不使用映射文件或在索引时或脚本期间修复?
答案 0 :(得分:3)
您看到的错误发生在查询解析时,即尚未执行任何操作。那时,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"
}
}
]
}
}
}