Elasticsearch(版本2.3)使用过滤类型查询的功能评分查询

时间:2016-06-01 05:33:43

标签: elasticsearch solr spring-data-elasticsearch

我对弹性搜索很新,我们正在从Solr迁移到弹性搜索。作为迁移的一部分,将现有的Solr查询转换为弹性搜索DSL查询。

以下是我使用功能评分功能部分完成的DSL查询。

{
  "query": {
    "function_score": {
      "query": {
        "filtered": {
          "match": {
            "name": "barack obama"
          },
          "filter": {
            "range": {
              "relevance": {
                "gte": 6
              }
            },
            "bool": {
              "must_not": [
                {
                  "terms": {
                    "classIds": [
                      199,
                      220
                    ],
                    "execution": "and"
                  }
                }
              ],
              "must": [
                {
                  "term": {
                    "classIds": 10597
                  }
                }
              ]
            }
          }
        }
      },
      "boost_mode": "replace",
      "functions": [
        {
          "script_score": {
            "script": {
              "lang": "groovy",
              "file": "calculate-score",
              "params": {
                "relevance_boost": 1,
                "class_penalize": 0.25
              }
            }
          }
        }
      ]
    }
  }
}

此查询在针对弹性搜索群集运行时返回错误。请帮我弄清楚问题。

这里计算得分是groovy脚本,它的工作正常,我用简单的查询测试了它。

以下是错误回复:

{
  "error": {
    "root_cause": [
      {
        "type": "query_parsing_exception",
        "reason": "[filtered] query does not support [match]",
        "index": "nodes_5e27a7d3-b370-40bd-9e71-cf04a36297c0",
        "line": 6,
        "col": 11
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "nodes_5e27a7d3-b370-40bd-9e71-cf04a36297c0",
        "node": "NOAwAtVwQS25egu7AIaHEg",
        "reason": {
          "type": "query_parsing_exception",
          "reason": "[filtered] query does not support [match]",
          "index": "nodes_5e27a7d3-b370-40bd-9e71-cf04a36297c0",
          "line": 6,
          "col": 11
        }
      }
    ]
  },
  "status": 400
}

这是我试图转换为弹性搜索的Solr查询:

SOLR QUERY (UNIQUE_NODE_CORE): q={!boost b="product(pow(field(relevance),1.0000),if(exists(query({!v='all_class_ids:226'})),0.25,1),if(exists(query({!v='all_class_ids:14106'})),0.25,1),if(exists(query({!v='all_class_ids:656'})),0.25,1))"}
raw_name:"barack obama"
&rows=1
&start=0
&sort=score desc,relevance desc
-&fq=class_id:"10597"
-fq=relevance:[6 TO *]
-&fq=-all_class_ids:"14127"
-&fq=-all_class_ids:"14106"
-&fq=-all_class_ids:"226"
&fl=ontology_id,url_friendly_name,name,score,raw_notable_for,property_207578

只需帮助运行带有功能评分的过滤查询。

1 个答案:

答案 0 :(得分:3)

干得好,你几乎就在那里,你只是错过了query查询中的filtered部分,以便包装match查询。同样,range过滤器可以插入bool/must。我知道,非常满口。

{
  "query": {
    "function_score": {
      "query": {
        "filtered": {
          "query": {
            "match": {
              "name": "barack obama"
            }
          },
          "filter": {
            "bool": {
              "must_not": [
                {
                  "terms": {
                    "classIds": [
                      199,
                      220
                    ],
                    "execution": "and"
                  }
                }
              ],
              "must": [
                {
                  "range": {
                    "relevance": {
                      "gte": 6
                    }
                  }
                },
                {
                  "term": {
                    "classIds": 10597
                  }
                }
              ]
            }
          }
        }
      },
      "boost_mode": "replace",
      "functions": [
        {
          "script_score": {
            "script": {
              "lang": "groovy",
              "file": "calculate-score",
              "params": {
                "relevance_boost": 1,
                "class_penalize": 0.25
              }
            }
          }
        }
      ]
    }
  }
}

请注意,自从ES 2.0以来,filtered查询已被弃用,您可以使用bool/must/filter查询重写它:

{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": {
            "match": {
              "name": "barack obama"
            }
          },
          "filter": [
            {
              "range": {
                "relevance": {
                  "gte": 6
                }
              }
            },
            {
              "term": {
                "classIds": 10597
              }
            }
          ],
          "must_not": [
            {
              "terms": {
                "classIds": [
                  199,
                  220
                ],
                "execution": "and"
              }
            }
          ]
        }
      },
      "boost_mode": "replace",
      "functions": [
        {
          "script_score": {
            "script": {
              "lang": "groovy",
              "file": "calculate-score",
              "params": {
                "relevance_boost": 1,
                "class_penalize": 0.25
              }
            }
          }
        }
      ]
    }
  }
}