计算来自多个条件的匹配数

时间:2019-05-07 21:23:32

标签: elasticsearch

我正在将游泳比赛的结果存储在elasticsearch中,以便能够以不同的方式分析和显示数据。每个结果都存储为单独的文档,以毫秒为单位。像这样:

{
  "swimmer": "xyz123",
  "stroke": "butterfly",
  "distance": 25,
  "time": 20250
}

但是,对于年轻的游泳者来说,当他们在五种不同的事件类型(不同的击球方式)中达到特定的时间时,就会获得一个奖项,我希望能够找到所有时间都低于指定时间的游泳者。五个事件(不同事件的时间不同)。

示例: 游泳者完成以下项目即获得中杯奖: -在47秒或更短时间内完成50m仰泳 -在31秒或更短时间内释放50m(爬行) -在51秒或更短时间内达到50m的蛙泳 -22秒以内25m蝴蝶 -1m40s或更短时间内达到100m混合泳。

我尝试对每个笔划的每个限制使用由bool /必须查询组成的bool /应该查询。对此,我在“游泳者”->“中风”中具有聚合(术语“聚合”),并且可以基于存储桶数来确定游泳者是否在5冲程中达到了水平。

但是,这将为所有达到任何限制的所有游泳者返回一个水桶,尽管还不是很多(至今)游泳者,但我发现这从长远来看是行不通的。

我是否想念某些东西(运气不好)?谁能推荐在单个查询中实现此目标的方法?

简化查询:

{
  "query": {
    "bool": {
      "should": [
        { //* backstroke, 50m, <47000ms *// },
        { //* freestroke, 50m, <41000ms *// },
        { //* breaststroke, 50m, <51000ms *// },
        { //* butterfly, 25m, <22000ms *// },
        { //* medley, 100m, <100000ms *// }
      ]
    }
  },
  "aggs": {
    "by_swimmer": {
      "terms": {
        "field": "swimmer"
      },
      "aggs": {
        "by_stroke": {
          "terms": {
            "field": "stroke"
          }
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

查询将返回与单个或多个should子句匹配的任何文档。 您正在创建一个存储桶,其中包含单个游泳者的所有文档,然后您将这些文档按笔划类型进行划分。由于您的初始查询结果包含与任何奖项匹配的所有文档,因此您最终将得到描述的结果。 有多种方法可以解决这个问题。

  1. 您需要对每个奖励进行单独的查询,在must子句中包含过滤器查询。这样可以确保仅选择与奖励过滤器匹配的文档。

  2. 您更改查询以选择所有文档,例如做一个match all。然后,您可以处理聚合中的逻辑。您对游泳者保持术语聚合,以在一个存储桶中获得与单个游泳者匹配的所有文档。然后,将filter aggregations嵌套在每个奖励的游泳者级别上,如果其中包含游泳者已完成奖励的任何文件。

示例2:

{
  "query" : {
    "match_all" : {}
  },
  "aggs": {
    "by_swimmer": {
      "terms": {
        "field": "swimmer"
      },
    "aggs": {
      "stroke_award": {
        "filter": {
            "bool": {
              "must": [{ //* backstroke, 50m, <47000ms *// }]
          }
        }
      },
      "freestroke_award": {
        "filter": {
            "bool": {
              "must": [ { //* freestroke, 50m, <41000ms *// }]
            }
          }
        },
        "breaststroke_award": {
          "filter": {
            "bool": {
              "must": [ { //* breaststroke, 50m, <51000ms *// }]
            }
          }
        },
        "butterfly_award": {
          "filter": {
            "bool": {
              "must": [ { //* butterfly, 25m, <22000ms *// }]
            }
          }
        },
          "medley_award": {
          "filter": {
            "bool": {
              "must": [ { //* medley, 100m, <100000ms *// }]
            }
          }
        }
      }
    }
  }
}

当其中一个存储桶中有文件时,将为游泳者颁奖。