Подсчет попаданий из нескольких условий - PullRequest
1 голос
/ 08 мая 2019

Я сохраняю результаты соревнований по плаванию, чтобы упростить поиск и представлять данные по-разному. Каждый результат сохраняется как отдельный документ, время в миллис. Как это:

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

Тем не менее, для молодых пловцов есть награда, когда они достигают определенного времени в пяти различных типах событий (различные удары), и я хотел бы иметь возможность найти всех пловцов, у которых время меньше указанного времени во всех пять событий (разное время для разных событий).

Пример: Средний кубок присуждается, когда пловец выполнил: - 50 м на спине за 47 секунд или меньше - 50 м бесплатно (ползать) за 31 секунду или меньше - 50-метровый удар молочной железы за 51 секунду или менее - 25-метровая бабочка за 22 секунды или меньше - 100м попурри за 1м40 с или менее.

Я пытался использовать запрос bool / should, состоящий из запроса bool / must, для каждого из ограничений на удар. На этом у меня есть агрегации (термин агрегация) на Swimmer -> Stroke, и я могу по количеству ведер определить, достиг ли пловец уровня за 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 голосов
/ 08 мая 2019

Запрос возвращает любой документ, который соответствует одному или нескольким пунктам must.Вы создаете контейнер, содержащий все документы одного пловца, а затем делите эти документы по типу штриха.Поскольку ваш первоначальный результат запроса содержит все документы, соответствующие любой награде, вы получите результат, который вы описали.Есть несколько подходов к этому.

  1. Вы делаете отдельный запрос для каждой награды, содержащий запрос фильтра в условии must.Это гарантирует, что будут выбраны только документы, соответствующие фильтру вознаграждений.

  2. Вы измените свой запрос, чтобы выбрать весь документ, например, сделать соответствовать всем .Затем вы обрабатываете свою логику в агрегатах.Вы сохраняете совокупность терминов для пловца, чтобы получить все документы, соответствующие одному пловцу, в одном ведре.Затем вы делаете вложенные совокупности фильтров на уровне пловца для каждой награды, если они содержат какие-либо документы, которые пловец выполнил.

Пример для 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 *// }]
            }
          }
        }
      }
    }
  }
}

Когда в одном из этих ведер есть документ, награда выплачивается пловцу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...