如何在ElasticSearch中进行搜索和分组?

时间:2017-08-18 11:33:21

标签: elasticsearch

我的ElasticSearch索引包含以下记录:

{
  "project" : "A",
  "updated" : <date>,
  "cost"    : 123
},
{
  "project" : "A",
  "updated" : <date>,
  "cost"    : 1
},
{
  "project" : "B",
  "updated" : <date>,
  "cost"    : 3
},
{
  "project" : "B",
  "updated" : <date>,
  "cost"    : 4
},
{
  "project" : "C",
  "updated" : <date>,
  "cost"    : 5
}

我试图画出&#34;成本&#34;选定项目的图表。 任何人都可以帮我构建一个查询来获得一个项目的成本和分组数据的总和吗? F.E.我想为项目选择数据&#34; A&#34; &安培; &#34; B&#34;得到类似的东西:

date1 ->
  projectA -> sum(cost)
  projectB -> sum(cost)
date2 ->
  projectA -> sum(cost)
  projectB -> sum(cost)

不知道如何修改此查询,该查询为一个项目提取数据:

    "query": {
      "bool": {
        "must": [
          {
            "match": {
              "project": {
                "query": <project>,
                "type": "phrase"
              }
            }
          },
          {
            "range": {
              "updated": {
                "gte": <startDate>,
                "format": "epoch_millis"
              }
            }
          }
        ]
      }
    },
    "aggs": {
      "3": {
        "date_histogram": {
          "field": "End_Time",
          "interval": "1M",
          "time_zone": "CST6CDT",
          "min_doc_count": 1
        },
        "aggs": {
          "2": {
            "sum": {
              "field": "cost"
            }
          }
        }
      }
    }
  

更新:谢谢大家!在你的帮助下,我写了一下查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "End_Time": {
              "gte": 1485892800000,
              "format": "epoch_millis"
            }
          }
        }
      ],
      "should": [
        {
          "match": {
            "Project_Name": {
              "query": "A",
              "type": "phrase"
            }
          }
        },
        {
          "match": {
            "Project_Name": {
              "query": "B",
              "type": "phrase"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "3": {
      "date_histogram": {
        "field": "End_Time",
        "interval": "1M",
        "time_zone": "CST6CDT",
        "min_doc_count": 1
      },
      "aggs": {
        "project_agg": {
          "terms": {
            "field": "Project_ID"
          },
          "aggs": {
            "2": {
              "sum": {
                "field": "Cost"
              }
            }
          }
        }
      }
    }
  }
}

但它返回了一些奇怪的东西:

"aggregations": {
 "3": {
  "buckets": [
    {
      "key_as_string": "2017-02-01T00:00:00.000-06:00",
      "key": 1485928800000,
      "doc_count": 17095,
      "project_agg": {
        "doc_count_error_upper_bound": 36,
        "sum_other_doc_count": 3503,
        "buckets": [
          {
            "2": {
              "value": 2536.8616891294323
            },
            "key": 834879987748,
            "doc_count": 2243
          },
          {
            "2": {
              "value": 3438.766646153458
            },
            "key": 497952557271,
            "doc_count": 1785
          },
          {
            "2": {
              "value": 13066.367076588496
            },
            "key": 1057394416300,
            "doc_count": 1736
          },
          ...

这是每月10个桶。我希望每个项目只能看到2个值。怎么了?

2 个答案:

答案 0 :(得分:1)

您需要在汇总费用之前汇总项目:

{
  "aggs": {
    "3": {
      "date_histogram": {
        "field": "End_Time",
        "interval": "1M",
        "time_zone": "CST6CDT",
        "min_doc_count": 1
      },
      "aggs": {
        "2": {
          "terms": {
            "field": "project"
          },
          "aggs": {
            "1": {
              "sum": {
                "field": "cost"
              }
            }
          }
        }
      }
    }
  }
}

对于过滤,它取决于您希望如何进行搜索。有关您可以使用的项目列表:

  "query": {
    "bool": {
      "must": [
        { "terms": { "project": [ "a", "b" ] } } //Assuming field is mapped as "analyzed"
      ]
    }
  }

如果你的地图包含.keyword变种,你可以格式化术语过滤器,如下所示: {&#34; terms&#34;:{&#34; project.keyword&#34;:[&#34; A&#34;,&#34; B&#34; ]}} //假设字段被映射为&#34; not_analyzed&#34;或者有一个关键字字段。 下面是一个如何在ES 5.5中将字段映射为&#34; text&#34;使用&#34; keword&#34;字段:

  "ShortTextContent" : {
    "type" : "text",
    "fields" : {
      "keyword" : {
        "type" : "keyword",
        "ignore_above" : 256
      }
    }
  }

在这种情况下,我可以使用&#34; ShortTextContent&#34;访问分析的版本。和使用&#34; ShortTextContent.keyword&#34;

的not_analyzed版本

答案 1 :(得分:1)

您编写的查询为您提供每月的总费用(无论项目如何),您需要在aggregation 3aggregation 2之间按项目分组另一个聚合。

如果您只想要项目AB,请在聚合中使用过滤器。

"size": 0,
   "aggs": {
      "project": {
         "filter": {
            "bool": {
               "must": [
                  {
                     "terms": {
                        "project": [
                           "a",
                           "b"
                        ]
                     }
                  }
               ]
            }
         },
         "aggs": {
            "3": {
               "date_histogram": {
                  "field": "End_Time",
                  "interval": "1M",
                  "time_zone": "CST6CDT",
                  "min_doc_count": 1
               },
               "aggs": {
                  "project_agg": {
                     "terms": {
                        "field": "project"
                     },
                     "aggs": {
                        "2": {
                           "sum": {
                              "field": "cost"
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }