我们如何减少 elasticsearch 查询子句的数量?
How can we decrease elasticsearch query clauses count?
我们编写了一个 elasticsearch 查询,用于从特定日期范围的索引中获取分组数据。但是,如果我们增加日期范围,我们的查询大小会随着动态添加的日期范围子句而增加。
动态增加查询样本
"query": {
"bool": {
"filter": [
{
"bool": {
"minimum_should_match": 1,
"must": [
{
"range": {
"startDate": {
"gte": "2018-05-28T21:00:00Z",
"lte": "2021-04-04T20:59:59Z"
}
}
}
],
"should": [
{
"bool": {
"must": [
{
"range": {
"startDate": {
"gte": "2019-12-24T04:30:00Z",
"lte": "2019-12-24T14:00:00Z"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"startDate": {
"gte": "2020-11-09T04:30:00Z",
"lte": "2020-11-09T14:00:00Z"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"startDate": {
"gte": "2020-07-28T14:00:00Z",
"lte": "2020-07-28T20:59:00Z"
}
}
}
]
}
}
]
}
},
{
"term": {
"tenantId": {
"value": "b29aadd8-b1bb-4754-ab26-b59eebe6d86a"
}
}
},
{
"term": {
"status.keyword": {
"value": "ProductionEnd"
}
}
},
{
"range": {
"startDate": {
"gte": "2018-05-28T21:00:00Z",
"lte": "2021-04-04T20:59:59Z"
}
}
}
]
}},
我们有基于时间的数据,我们想像上面那样按日期时间过滤它们,但我们想过滤 3 个月范围内的数据,范围过滤器太多,我们得到一个错误("too_many_clauses") 因为查询大小。所以,我们想减少查询子句。我们如何重写查询?
谢谢
我认为您的选择之一是将如此大的应该查询拆分为更小的应该查询块。这样 bool 查询就不会扩展 1024 个子句的限制。
bool
|___should
| |___should query with 1024 range queries
| |___should query with 1024 range queries
| |___... range queries
这是我所说的一个简单例子
var ranges = Enumerable.Range(0, 3000).Select((x, i) =>
new QueryContainer(new DateRangeQuery {Name = $"query_{i}", Field = $"date", GreaterThan = "now"}));
var part1 = ranges.Take(1024)
.Aggregate((agg, q) => agg || q);
var part2 = ranges.Skip(1024).Take(1024)
.Aggregate((agg, q) => agg || q);
var searchResponse = await client.SearchAsync<object>(s => s
.Query(q => q.Bool(b => b.Should(part1, part2))));
希望对您有所帮助。
我们编写了一个 elasticsearch 查询,用于从特定日期范围的索引中获取分组数据。但是,如果我们增加日期范围,我们的查询大小会随着动态添加的日期范围子句而增加。 动态增加查询样本
"query": {
"bool": {
"filter": [
{
"bool": {
"minimum_should_match": 1,
"must": [
{
"range": {
"startDate": {
"gte": "2018-05-28T21:00:00Z",
"lte": "2021-04-04T20:59:59Z"
}
}
}
],
"should": [
{
"bool": {
"must": [
{
"range": {
"startDate": {
"gte": "2019-12-24T04:30:00Z",
"lte": "2019-12-24T14:00:00Z"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"startDate": {
"gte": "2020-11-09T04:30:00Z",
"lte": "2020-11-09T14:00:00Z"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"startDate": {
"gte": "2020-07-28T14:00:00Z",
"lte": "2020-07-28T20:59:00Z"
}
}
}
]
}
}
]
}
},
{
"term": {
"tenantId": {
"value": "b29aadd8-b1bb-4754-ab26-b59eebe6d86a"
}
}
},
{
"term": {
"status.keyword": {
"value": "ProductionEnd"
}
}
},
{
"range": {
"startDate": {
"gte": "2018-05-28T21:00:00Z",
"lte": "2021-04-04T20:59:59Z"
}
}
}
]
}},
我们有基于时间的数据,我们想像上面那样按日期时间过滤它们,但我们想过滤 3 个月范围内的数据,范围过滤器太多,我们得到一个错误("too_many_clauses") 因为查询大小。所以,我们想减少查询子句。我们如何重写查询?
谢谢
我认为您的选择之一是将如此大的应该查询拆分为更小的应该查询块。这样 bool 查询就不会扩展 1024 个子句的限制。
bool
|___should
| |___should query with 1024 range queries
| |___should query with 1024 range queries
| |___... range queries
这是我所说的一个简单例子
var ranges = Enumerable.Range(0, 3000).Select((x, i) =>
new QueryContainer(new DateRangeQuery {Name = $"query_{i}", Field = $"date", GreaterThan = "now"}));
var part1 = ranges.Take(1024)
.Aggregate((agg, q) => agg || q);
var part2 = ranges.Skip(1024).Take(1024)
.Aggregate((agg, q) => agg || q);
var searchResponse = await client.SearchAsync<object>(s => s
.Query(q => q.Bool(b => b.Should(part1, part2))));
希望对您有所帮助。