You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Elasticsearch Watcher遍历聚合桶并为每个桶发送对应邮件

问题分析

你的问题核心在于transform脚本把所有桶的Top Hits数据合并成了一个列表,同时foreach循环里的邮件正文没有正确引用当前迭代的桶数据,导致每封邮件都输出了所有国家的内容。其实不需要提前用transform聚合数据,foreach本身就可以直接遍历每个桶,我们只需要在循环内处理单个桶的hits即可。

修正后的Watcher配置
{
  "trigger": {
    "schedule": { "interval": "30m" }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": [ "my-idx" ],
        "rest_total_hits_as_int": true,
        "body": { 
          // 保留你原有的聚合查询逻辑
        }
      }
    }
  },
  // 移除不必要的transform,直接在foreach中处理单个桶
  "actions": {
    "send_email": {
      "foreach": "ctx.payload.aggregations.agg1.buckets",
      "max_iterations": 100,
      "email": {
        "profile": "standard",
        "to": [ "test@gmail.com" ],
        // 主题加入当前桶的国家名称,更直观
        "subject": "Agent Report for {{ctx.payload.key}}",
        "body": {
          "html": """
            <html>
              <body>
                <table style="background-color: #f9f9ff; border-collapse: collapse;">
                  <thead>
                    <tr>
                      <th style="border: 1px solid #ddd; padding: 8px;">Agent Name</th>
                      <th style="border: 1px solid #ddd; padding: 8px;">Timestamp</th>
                      <th style="border: 1px solid #ddd; padding: 8px;">Country</th>
                    </tr>
                  </thead>
                  <tbody>
                    {% for hit in ctx.payload.agg2.hits.hits %}
                    <tr>
                      <td style="border: 1px solid #ddd; padding: 8px;">{{hit._source.agent.name}}</td>
                      <td style="border: 1px solid #ddd; padding: 8px;">{{hit._source.@timestamp}}</td>
                      <td style="border: 1px solid #ddd; padding: 8px;">{{hit._source.country}}</td>
                    </tr>
                    {% endfor %}
                  </tbody>
                </table>
              </body>
            </html>
          """
        }
      }
    }
  }
}
关键修改点说明
  1. 移除Transform脚本:不需要提前把所有桶的hits合并成一个列表,foreach会遍历每个桶,每次迭代的ctx.payload就是当前的单个桶对象(比如India或USA的桶)。
  2. 动态邮件主题:用{{ctx.payload.key}}获取当前桶的国家名称,让邮件主题更清晰。
  3. 遍历当前桶的Hits:在邮件正文中使用{% for hit in ctx.payload.agg2.hits.hits %}循环,逐个输出当前国家下的agent信息,完全符合你需要的格式。
  4. 表格化展示:把内容整理成表格,比纯文本更易读,你也可以根据需求改回纯文本格式。
纯文本格式的备选正文(如果不需要表格)

如果你更倾向于纯文本格式的邮件正文,可以把body.html换成body.text:

"body": {
  "text": """
    {% for hit in ctx.payload.agg2.hits.hits %}
    agent.name: "{{hit._source.agent.name}}"
    @timestamp: {{hit._source.@timestamp}}
    country: "{{hit._source.country}}"
    
    {% endfor %}
  """
}

内容的提问来源于stack exchange,提问作者Bhavya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:08:10