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

如何在Elasticsearch多字段上实现工作日嵌套数据聚合

解决方案

一、基于现有映射的聚合方案

当前映射中workingDays为嵌套字段,且每个日期(mon/tue等)又是独立的嵌套子字段,这种结构下可以通过**脚本化指标聚合(scripted_metric)**直接生成你需要的结果格式:

{
  "size": 0,
  "aggs": {
    "available_days": {
      "scripted_metric": {
        "init_script": "state.days = [:]",
        "map_script": """
          def workingDays = params._source.workingDays;
          if (workingDays == null) return;
          
          // 遍历所有日期字段(根据实际情况补充完整日期)
          def days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
          for (def day : days) {
            def dayData = workingDays[day];
            if (dayData != null && dayData.availability == true) {
              def title = dayData.title;
              if (title != null) {
                state.days[title] = (state.days[title] ?: 0) + 1;
              }
            }
          }
        """,
        "combine_script": "return state.days",
        "reduce_script": """
          def result = [:];
          states.each { bucket ->
            bucket.each { entry ->
              result[entry.key] = (result[entry.key] ?: 0) + entry.value;
            }
          }
          // 转换为目标格式
          def buckets = [];
          result.each { k, v ->
            buckets.add(['key': k, 'doc_count': v]);
          }
          return ['buckets': buckets];
        """
      }
    }
  }
}

说明:

  • 该聚合会遍历每个文档的workingDays字段,检查每个日期的availability是否为true,收集对应的title并统计出现次数
  • 最终结果会直接返回你需要的buckets数组结构

二、优化映射后的更优方案

现有映射设计不利于聚合操作(每个日期作为独立嵌套字段,需逐个处理),建议将workingDays修改为数组型嵌套字段,映射调整如下:

"workingDays": {
  "type": "nested",
  "properties": {
    "dayOfWeek": {
      "type": "keyword"
    },
    "availability": {
      "type": "boolean"
    },
    "title": {
      "type": "text",
      "fields": {
        "keyword": {
          "type": "keyword"
        }
      }
    },
    "notes": {
      "type": "text"
    }
  }
}

对应的文档结构改为:

"workingDays": [
  {
    "dayOfWeek": "mon",
    "availability": true,
    "title": "Monday",
    "notes": ""
  },
  {
    "dayOfWeek": "tue",
    "availability": false,
    "title": "Tuesday",
    "notes": "On Tuesdays, drop off and pick up times must be scheduled between 12pm to 2pm"
  }
]

此时只需简单的嵌套聚合即可得到目标结果:

{
  "size": 0,
  "aggs": {
    "working_days_nested": {
      "nested": {
        "path": "workingDays"
      },
      "aggs": {
        "filter_available": {
          "filter": {
            "term": {
              "workingDays.availability": true
            }
          },
          "aggs": {
            "day_title_count": {
              "terms": {
                "field": "workingDays.title.keyword"
              }
            }
          }
        }
      }
    }
  }
}

结果直接从working_days_nested.filter_available.day_title_count.buckets获取,完全符合你需要的格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 16:06:59