嵌套内部命中的 Elasticsearch 聚合
Elasticsearch aggregations on nested inner hits
我在 Elasticsearch 中获取了大量数据。我的文档有一个名为 "records" 的嵌套字段,其中包含具有多个字段的对象列表。
我希望能够从记录列表中查询特定对象,因此我在查询中使用了 inner_hits 字段,但这没有帮助,因为聚合使用大小 0,所以没有返回结果.
我没有成功使聚合只对 inner_hits 有效,因为无论查询如何,聚合 returns 都会对记录中的所有对象产生结果。
这是我正在使用的查询:
(每个文档有first_timestamp和last_timestamp字段,记录列表中的每个对象都有时间戳字段)
curl -XPOST 'localhost:9200/_msearch?pretty' -H 'Content-Type: application/json' -d'
{
"index":[
"my_index"
],
"search_type":"count",
"ignore_unavailable":true
}
{
"size":0,
"query":{
"filtered":{
"query":{
"nested":{
"path":"records",
"query":{
"term":{
"records.data.field1":"value1"
}
},
"inner_hits":{}
}
},
"filter":{
"bool":{
"must":[
{
"range":{
"first_timestamp":{
"gte":1504548296273,
"lte":1504549196273,
"format":"epoch_millis"
}
}
}
],
}
}
}
},
"aggs":{
"nested_2":{
"nested":{
"path":"records"
},
"aggs":{
"2":{
"date_histogram":{
"field":"records.timestamp",
"interval":"1s",
"min_doc_count":1,
"extended_bounds":{
"min":1504548296273,
"max":1504549196273
}
}
}
}
}
}
}'
您的查询非常复杂。
简而言之,这是您请求的查询:
{
"size": 0,
"aggregations": {
"nested_A": {
"nested": {
"path": "records"
},
"aggregations": {
"bool_aggregation_A": {
"filter": {
"bool": {
"must": [
{
"term": {
"records.data.field1": "value1"
}
}
]
}
},
"aggregations": {
"reverse_aggregation": {
"reverse_nested": {},
"aggregations": {
"bool_aggregation_B": {
"filter": {
"bool": {
"must": [
{
"range": {
"first_timestamp": {
"gte": 1504548296273,
"lte": 1504549196273,
"format": "epoch_millis"
}
}
}
]
}
},
"aggregations": {
"nested_B": {
"nested": {
"path": "records"
},
"aggregations": {
"my_histogram": {
"date_histogram": {
"field": "records.timestamp",
"interval": "1s",
"min_doc_count": 1,
"extended_bounds": {
"min": 1504548296273,
"max": 1504549196273
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
现在,让我通过聚合的名称来解释每一步:
- 大小:0 -> 我们对命中不感兴趣,只对聚合感兴趣
- nested_A ->
data.field1
正在记录中,因此我们将范围扩大到记录
- bool_aggregation_A -> 按
data.field1
筛选:value1
- reverse_aggregation ->
first_timestamp
不在嵌套文档中,我们需要从记录 中排除范围
- bool_aggregation_B -> 按
first_timestamp
范围过滤
- nested_B -> 现在,我们再次将
timestamp
字段(位于记录下) 的记录范围
- my_histogram -> 最后,按
timestamp
字段 聚合日期直方图
Inner_hits 弹性搜索不支持聚合。其背后的原因是 inner_hits 是一个非常昂贵的操作,在 inner_hits 上应用聚合就像操作复杂性呈指数增长。
Here is the github link of the issue.
如果您想在 inner_hits 上聚合,您可以使用以下方法:
- 进行灵活的查询,您只从弹性中获得所需的命中并对其进行聚合。重复多次以获得所有命中并同时聚合。这种方法可能会导致您进行多个搜索查询,这是不可取的。
- 您可以通过编写智能聚合解析器和 运行 这些解析器来处理来自 elasticsearch 的响应的聚合逻辑。这种方法稍微好一些,但是您需要根据不断变化的需求维护解析器。
我个人建议您更改 elasticsearch 中的数据映射样式,以便您能够 运行 对其进行聚合。
你也可以这样查看代码
PUT records
{
"mappings": {
"properties": {
"records": {
"type": "nested"
}
}
}
}
POST records/_doc
{
"records": [
{
"data": "test1",
"value": 1
},
{
"data": "test2",
"value": 2
}
]
}
GET records/_search
{
"size": 0,
"aggs": {
"all_nested_count": {
"nested": {
"path": "records"
},
"aggs": {
"bool_aggs": {
"filter": {
"bool": {
"must": [
{
"term": {
"records.data": "test2"
}
}
]
}
},
"aggs": {
"filtered_aggs": {
"sum": {
"field": "records.value"
}
}
}
}
}
}
}
}
参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/inner-hits.html
我在 Elasticsearch 中获取了大量数据。我的文档有一个名为 "records" 的嵌套字段,其中包含具有多个字段的对象列表。
我希望能够从记录列表中查询特定对象,因此我在查询中使用了 inner_hits 字段,但这没有帮助,因为聚合使用大小 0,所以没有返回结果.
我没有成功使聚合只对 inner_hits 有效,因为无论查询如何,聚合 returns 都会对记录中的所有对象产生结果。
这是我正在使用的查询: (每个文档有first_timestamp和last_timestamp字段,记录列表中的每个对象都有时间戳字段)
curl -XPOST 'localhost:9200/_msearch?pretty' -H 'Content-Type: application/json' -d'
{
"index":[
"my_index"
],
"search_type":"count",
"ignore_unavailable":true
}
{
"size":0,
"query":{
"filtered":{
"query":{
"nested":{
"path":"records",
"query":{
"term":{
"records.data.field1":"value1"
}
},
"inner_hits":{}
}
},
"filter":{
"bool":{
"must":[
{
"range":{
"first_timestamp":{
"gte":1504548296273,
"lte":1504549196273,
"format":"epoch_millis"
}
}
}
],
}
}
}
},
"aggs":{
"nested_2":{
"nested":{
"path":"records"
},
"aggs":{
"2":{
"date_histogram":{
"field":"records.timestamp",
"interval":"1s",
"min_doc_count":1,
"extended_bounds":{
"min":1504548296273,
"max":1504549196273
}
}
}
}
}
}
}'
您的查询非常复杂。 简而言之,这是您请求的查询:
{
"size": 0,
"aggregations": {
"nested_A": {
"nested": {
"path": "records"
},
"aggregations": {
"bool_aggregation_A": {
"filter": {
"bool": {
"must": [
{
"term": {
"records.data.field1": "value1"
}
}
]
}
},
"aggregations": {
"reverse_aggregation": {
"reverse_nested": {},
"aggregations": {
"bool_aggregation_B": {
"filter": {
"bool": {
"must": [
{
"range": {
"first_timestamp": {
"gte": 1504548296273,
"lte": 1504549196273,
"format": "epoch_millis"
}
}
}
]
}
},
"aggregations": {
"nested_B": {
"nested": {
"path": "records"
},
"aggregations": {
"my_histogram": {
"date_histogram": {
"field": "records.timestamp",
"interval": "1s",
"min_doc_count": 1,
"extended_bounds": {
"min": 1504548296273,
"max": 1504549196273
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
现在,让我通过聚合的名称来解释每一步:
- 大小:0 -> 我们对命中不感兴趣,只对聚合感兴趣
- nested_A ->
data.field1
正在记录中,因此我们将范围扩大到记录 - bool_aggregation_A -> 按
data.field1
筛选:value1 - reverse_aggregation ->
first_timestamp
不在嵌套文档中,我们需要从记录 中排除范围
- bool_aggregation_B -> 按
first_timestamp
范围过滤 - nested_B -> 现在,我们再次将
timestamp
字段(位于记录下) 的记录范围
- my_histogram -> 最后,按
timestamp
字段 聚合日期直方图
Inner_hits 弹性搜索不支持聚合。其背后的原因是 inner_hits 是一个非常昂贵的操作,在 inner_hits 上应用聚合就像操作复杂性呈指数增长。 Here is the github link of the issue.
如果您想在 inner_hits 上聚合,您可以使用以下方法:
- 进行灵活的查询,您只从弹性中获得所需的命中并对其进行聚合。重复多次以获得所有命中并同时聚合。这种方法可能会导致您进行多个搜索查询,这是不可取的。
- 您可以通过编写智能聚合解析器和 运行 这些解析器来处理来自 elasticsearch 的响应的聚合逻辑。这种方法稍微好一些,但是您需要根据不断变化的需求维护解析器。
我个人建议您更改 elasticsearch 中的数据映射样式,以便您能够 运行 对其进行聚合。
你也可以这样查看代码
PUT records
{
"mappings": {
"properties": {
"records": {
"type": "nested"
}
}
}
}
POST records/_doc
{
"records": [
{
"data": "test1",
"value": 1
},
{
"data": "test2",
"value": 2
}
]
}
GET records/_search
{
"size": 0,
"aggs": {
"all_nested_count": {
"nested": {
"path": "records"
},
"aggs": {
"bool_aggs": {
"filter": {
"bool": {
"must": [
{
"term": {
"records.data": "test2"
}
}
]
}
},
"aggs": {
"filtered_aggs": {
"sum": {
"field": "records.value"
}
}
}
}
}
}
}
}
参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/inner-hits.html