query_string 和范围同时
query_string and range at the same time
如何在同一查询中同时包含 query_string
和 range
?
我正在将此发送给 /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\"];
如果我删除 range
或 query_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]"
}
}
如何在同一查询中同时包含 query_string
和 range
?
我正在将此发送给 /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\"];
如果我删除 range
或 query_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]"
}
}