упругая: запрос суммы отфильтрованного подмножества вложенных документов - PullRequest
1 голос
/ 30 мая 2019

Рассмотрим документ (запись), подобный этому, в индексе эластичного поиска:

    {
      title: "I love ice cream!"
      comments: [
        {
          body: "me too!",
          reaction: 'positive',
          likes: 20
        },
        {
          body: "huh!",
          reaction: 'sarcastic',
          likes: 5
        }
      ]
    }

Комментарии - это поле типа nested.

Как может упругая ответить на это: Дайте мне все посты, где общая сумма лайков в «саркастических» комментариях превышает 100. Я открыт для любого другого способа моделирования данных, который помогает ответить на такие запросы.

1 Ответ

2 голосов
/ 31 мая 2019

Эту проблему можно решить, используя агрегацию селектора сегментов .

Отображение:

{
  "index1" : {
    "mappings" : {
      "properties" : {
        "comments" : {
          "type" : "nested",
          "properties" : {
            "body" : {
              "type" : "text"
            },
            "likes" : {
              "type" : "integer"
            },
            "reaction" : {
              "type" : "text"
            }
          }
        },
        "title" : {
          "type" : "keyword"
        }
      }
    }
  }
}

Данные:

  "hits" : [
      {
        "_index" : "index1",
        "_type" : "_doc",
        "_id" : "p0y9DGsBfPdKzuAGdQrm",
        "_score" : 1.0,
        "_source" : {
          "title" : "I love ice cream!",
          "comments" : [
            {
              "body" : "me too!",
              "reaction" : "positive",
              "likes" : 20
            },
            {
              "body" : "huh!",
              "reaction" : "sarcastic",
              "likes" : 5
            }
          ]
        }
      },
      {
        "_index" : "index1",
        "_type" : "_doc",
        "_id" : "qEy9DGsBfPdKzuAGnwox",
        "_score" : 1.0,
        "_source" : {
          "title" : "I hate ice cream!",
          "comments" : [
            {
              "body" : "me too!",
              "reaction" : "positive",
              "likes" : 10
            },
            {
              "body" : "huh!",
              "reaction" : "sarcastic",
              "likes" : 5
            }
          ]
        }
      }
    ]
  }

Запрос:

GET index1/_search
{
  "size": 0,
  "aggs": {
    "title": {
      "terms": {
        "field": "title"
      },
      "aggs": {
        "comments": {
          "nested": {
            "path": "comments"
          },
          "aggs": {
            "reaction": {
              "filter": {
                "term": {
                  "comments.reaction": "positive"
                }
              },
              "aggs": {
                "total_likes": {
                  "sum": {
                    "field": "comments.likes"
                  }
                }
              }
            }
          }
        },
        "total_likes_filter": {
          "bucket_selector": {
            "buckets_path": {
              "likes": "comments>reaction>total_likes"
            },
            "script": "params.likes > 15"
          }
        }
      }
    }
  }
}

Результат:

  "aggregations" : {
    "title" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "I love ice cream!",
          "doc_count" : 1,
          "comments" : {
            "doc_count" : 2,
            "reaction" : {
              "doc_count" : 1,
              "total_likes" : {
                "value" : 20.0
              }
            }
          }
        }
      ]
    }
  }
}

Ведро содержит только "Я люблю мороженое!"там, где общее количество положительных реакций выше 20. Я ненавижу мороженое!имеет общую сумму 5 для положительной реакции, поэтому она не включена.

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