当前位置: 首页 > 知识库问答 >
问题:

嵌套内嵌件上的弹性搜索聚合

龙隐水
2023-03-14

我在Elasticsearch中获得了大量数据。我的douments有一个名为“records”的嵌套字段,它包含一个包含多个字段的对象列表。

我希望能够从记录列表中查询特定的对象,因此我在查询中使用了inner_hits字段,但是这没有帮助,因为聚合使用大小0,所以没有返回结果。

我没有成功地使一个聚集只对inner_hits有效,因为无论查询是什么,聚集都返回记录中所有对象的结果。

这是我正在使用的查询:(每个文档都有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
                          }
                     }
                }
           }
      }
   }
}'

共有3个答案

荀博
2023-03-14

你也可以像这样检查代码

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

韦正业
2023-03-14

弹性搜索不支持Inner_hits聚合。其背后的原因是,inner_hits是一种非常昂贵的操作,并且对inner_hits应用聚合就像操作复杂性呈指数级增长一样。这是该问题的github链接。

如果您想要对inner_hits进行聚合,您可以使用以下方法:

  1. 进行灵活的查询,其中仅从弹性获得所需的命中并对其进行聚合。重复多次以获得所有命中并同时聚合。这种方法可能会导致您进行多次搜索查询,这是不可取的。
  2. 您可以通过编写智能聚合解析器来使应用程序层处理聚合逻辑,并根据来自 elasticsearch 的响应运行这些解析器。这种方法稍微好一点,但是根据不断变化的需求维护解析器会产生开销。

我个人建议您在弹性搜索中更改数据映射样式,以便能够在其上运行聚合。

元英朗
2023-03-14

您的查询相当复杂。简而言之,以下是您请求的查询:

{
  "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-
 类似资料:
  • 我已经为一个问题挣扎了一段时间,所以我想我应该通过stackoverflow来解决这个问题。 “我的文档类型”有一个标题、一个语言字段(用于筛选)和一个分组id字段(我省略了所有其他字段以保持重点) 搜索文档时,我希望找到包含标题中文本的所有文档。对于每个唯一的分组id,我只需要一个文档。 我一直在关注tophits聚合,从我所看到的情况来看,它应该能够解决我的问题。 对我的索引运行此查询时: 我

  • 如何获得空数组和美国的结果和

  • 我有一个弹性搜索索引集合,如下所示, 现在我需要通过将与其值匹配来搜索文档。(是一些字段,其值存储在中)例如。对于字段,如果它是,则应与上述文档匹配。 我尝试将其映射为嵌套对象,但我无法编写查询来搜索与其相应值匹配的2个或更多的键id。

  • Elasticsearch版本:2.3.3 基本上,标题说明了一切。如果二个嵌套聚合下使用reverse_nested,尽管文档似乎通过限定范围(请参阅结果中的最后一个字段),但其后面的聚合不会以某种方式工作。 这里我准备了一个例子——一个文档是一个学生的注册日期和考试历史。 映射: 试验文件: 聚合查询(无实际意义): 结果是: ...您可以在其中看到聚合“newest_exam_date”不起

  • 我是ES新手,正在努力解决嵌套聚合问题。这是我的虚拟数据对象([这是我的数据对象][1][1]:https://i.stack.imgur.com/X7oaM.png). 我只是想把“现代”领域的成本降到最低。 我已经阅读了以下关于我试图解决的问题的帖子。他们都没有帮助我解决问题 -弹性搜索6嵌套查询聚合-https://www.elastic.co/guide/en/elasticsearch/

  • 我试图为一个业务场景制定一个查询,其中我们有一个名为“types”的嵌套字段类型(即类似于字符串的ArrayList)。下面是以“类型”作为字段之一的索引文档示例。 文件1:{“类型”:[{“标签”:“对话”,},{“标签”:“暴力”,},{“标签”:“语言”,}} 文档2:{“类型”:[{“标签”:“对话框”,}} 现在,要求搜索查询最多匹配字段值中的一个值,即如果用户搜索“对话框”,那么它应该