query_string 和范围同时

query_string and range at the same time

如何在同一查询中同时包含 query_stringrange

我正在将此发送给 /myindex/mytype/_search/?search_type=count:

 {"query": {"query_string": {"query": "field1:value1"},
            "range": {"time": {"gt": "2014-11-01T00:00:00Z",
                               "lte": "2014-11-01T03:00:00Z"}}},
  "aggs": {"counts": {"date_histogram": {"field": "time",
                                         "interval": "minute"}}}}

但是 ES 给我这个错误:

ElasticsearchParseException[Expected field name but got START_OBJECT \"range\"];

如果我删除 rangequery_string,它工作得很好,但没有非常需要的过滤:)

我相信,你想要这样的东西:

{
    "query": {
        "bool": {
            "must": [
                {
                    "range": {
                        "time": {
                            "gt": "2014-11-01T00:00:00Z",
                            "lte": "2014-11-01T03:00:00Z"
                        }
                    }
                },
                {
                    "query_string": {
                        "query": "field1:value1"
                    }
                }
            ]
        }
    }
}

Elasticsearch 似乎不允许您在单个 "query" 标签下将多个内容链接在一起。

(抱歉格式化,我无法让 { 看起来漂亮且排列整齐。)

根据您的说法,您似乎想要组合多个查询以缩小计算聚合的范围。

首先,这可以使用 bool 查询 (documentation) 来实现,它让您决定文档是否必须匹配两个查询(参见 must 子句)或至少查询之一(参见 should 子句)。

假设您希望结果文档匹配两个 查询,语法为:

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            ...
          }
        },
        {
          "range": {
            ...
          }
        }
      ]
    }
  }
}

这会起作用,但这不是最佳的查询方式。可以对其进行优化,因为您的 range 查询具有等效的过滤器。

使用过滤器版本通常会更快,因为它会跳过分数计算,并且会命中大多数过滤器类型的缓存(有关 differences between queries and filters here 的更多信息)。

但是,过滤器不能直接在 query 属性中使用,您必须将其包装在具有两个属性的 filtered 查询中:

  • query : 要过滤的查询
  • filter : 与您的查询结合的过滤器

最后,您会遇到这样的查询:

{
  "query": {
    "filtered": {
      "query": {
        "query_string": {
          "query": "field1:value1"
        }
      },
      "filter": {
        "range": {
          "time": {
            "gt": "2014-11-01T00:00:00Z",
            "lte": "2014-11-01T03:00:00Z"
          }
        }
      }
    }
  },
  "aggs": {
    "counts": {
      "date_histogram": {
        "field": "time",
        "interval": "minute"
      }
    }
  }
}

根据 docs,现在可以仅使用 query_string 参数执行此操作,如下所示:

{
  "query_string": {
    "query": "field1:value1 AND time:[2014-11-01T00:00:00Z TO 2014-11-01T03:00:00Z]"
  }
}