Elasticsearch Painless根据嵌套元素计算得分

时间:2017-10-20 16:43:52

标签: elasticsearch elasticsearch-painless

注意:我最初发布这个问题的方式略有不同,不值得更新,因为阅读后我学到了更多。

要求

搜索文档并根据文档中的嵌套元素计算自定义分数。

结构

{
  "mappings": {
    "book": {
      "properties": {
        "title":        { "type": "string", "index": "not_analyzed" },
        "topics": {
          "type": "nested",
          "properties": {
            "title":   { "type": "string", "index": "not_analyzed" },
            "weight":  { "type": "int" }
          }
        }
      }
    }
  }
}

示例查询

{
  "query": {
    "function_score": {
      "query": {
        "term": { "title": "The Magical World of Spittle" }
      },
      "script_score": {
        "script": {
          "lang": "painless",
          "inline": "int score = 0; for(int i = 0; i < doc['topics'].values.length; i++) { score += doc['topics'][i].weight; } return score;",
          "params": {
            "default_return_value": 100
          }
        }
      }
    }
  }
}

孤立无痛

int score = 0;
for(int i = 0; i < doc['topics'].values.length; i++) {
  score += doc['topics'][i].weight;
}
return score;

错误

  

在使用类型[book]

进行映射时找不到[主题]的字段

问题

  • 怎么了?
  • 怎么办?

1 个答案:

答案 0 :(得分:6)

嵌套文档存储在索引中的不同文档中,因此您无法通过父文档中的doc值访问它们。您需要使用源文档并导航到topics.weight属性,如下所示:

孤立无痛:

int score = 0; 
for(int i = 0; i < params._source['topics'].size(); i++) { 
    score += params._source['topics'][i].weight; 
}
return score;

完整查询:

{
  "query": {
    "function_score": {
      "query": {
        "term": { "title": "Book 1" }
      },
      "script_score": {
        "script": {
          "lang": "painless",
          "inline": "int score = 0; for(int i = 0; i < params._source['topics'].size(); i++) { score += params._source['topics'][i].weight; } return score;",
          "params": {
            "default_return_value": 100
          }
        }
      }
    }
  }
}

PS:另请注意,int类型不存在,它是integer