用于过滤器术语的Elasticsearch DSL语法

时间:2019-07-09 16:42:47

标签: elasticsearch

我有一个弹性搜索查询,可以与multi_match和range过滤器一起使用,但是我无法确定添加术语过滤器的正确语法。

我使用的是Elasticsearch 7.1.0版。

这是有效的查询:

{
    "body": {
        "query": {
            "bool": {
                "must": {
                    "multi_match": {
                        "query": "nuclear power"
                    }
                },
                "filter": {
                    "range": {
                        "displaydate": {
                            "gte": "2019-07-02T16:26:04Z"
                        }
                    }
                }
            }
        }
    }
}

这将返回索引中与词组“核电”匹配且显示日期在2019-07-02 16:26之后的所有文档。

我现在希望能够过滤查询,以便它只返回某种类型的结果。索引中有一个称为object_type的字段,用于存储索引中每个项目的对象类型。

我想返回对象类型为“ Core_Page”或“ Module_Page”的结果。我使用“条款”代替“条款”,因为“条款”不支持值数组。

这是我添加术语过滤器的方式:

{
    "body": {
        "query": {
            "bool": {
                "must": {
                    "multi_match": {
                        "query": "nuclear power"
                    }
                },
                "filter": {
                    "terms": {
                        "object_type": [
                            "Core_Page",
                            "Module_Page"
                        ]
                    },
                    "range": {
                        "displaydate": {
                            "gte": "2019-07-02T16:16:50Z"
                        }
                    }
                }
            }
        }
    }
}

但是现在我从ElasticSearch收到解析错误:

Elasticsearch\Common\Exceptions\BadRequest400Exception: 
{
  "error":
    {"root_cause":
        [
            {
                "type":"parsing_exception",
                "reason":"[terms] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",
                "line":1,
                "col":142
             }
         ],

         "type":"parsing_exception",
         "reason":"[terms] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",
         "line":1,
         "col":142
    },
    "status":400
}

如何构造查询,以便使ElasticSearch解析器有意义?

2 个答案:

答案 0 :(得分:3)

当您有多个过滤器时,需要在数组中指定它们,如下所示:

{
  "body": {
    "query": {
      "bool": {
        "must": {
          "multi_match": {
            "query": "nuclear power"
          }
        },
        "filter": [
          {
            "terms": {
              "object_type": [
                "Core_Page",
                "Module_Page"
              ]
            }
          },
          {
            "range": {
              "displaydate": {
                "gte": "2019-07-02T16:16:50Z"
              }
            }
          }
        ]
      }
    }
  }
}

mustmust_notshould相同

答案 1 :(得分:0)

这是我最终得到的工作代码。

我使用“匹配”而不是“术语”,因为我想匹配原始值而不是处理后的值。 Elasticsearch在索引文本字符串时对其进行处理。它会小写并删除标点符号。 “期限”与该处理后的值进行比较。匹配将与原始值进行比较。

{
    "body": {
        "query": {
            "bool": {
                "must": {
                    "multi_match": {
                        "query": "nuclear power"
                    }
                },
                "filter": [
                    {
                        "bool": {
                            "should": [
                                {
                                    "match": {
                                        "object_type": "Module_Page"
                                    }
                                },
                                {
                                    "match": {
                                        "object_type": "Core_Page"
                                    }
                                }
                            ]
                        }
                    },
                    {
                        "range": {
                            "displaydate": {
                                "gte": "2019-07-03T12:54:32Z"
                            }
                        }
                    }
                ]
            }
        }
    }
}