Elasticsearch: распределение поля по отношению к другим полям

#python #elasticsearch

#python #elasticsearch

Вопрос:

У меня есть база данных elasticsearch с элементами вида

 record = {
            'diagnosis': self.diagnosis,
            'vignette': self.vignette,
            'symptoms': self.symptoms_list,
            'care': self.care_level_string,
            'age': self.age,
            'gender': self.gender
        }
  

Мне нужен запрос, который возвращает распределение 'age' (float), и другой, который возвращает распределение 'gender' (строка с 2 параметрами) по отношению к 'care' (строка с 3 параметрами).

Что означает, например, если в базе данных было

 1. care='a', age=1.0, gender='m'
2. care='b', age=2.0, gender='m'
3. care='c', age=1.0, gender='m'
4. care='a', age=1.0, gender='m'
5. care='b', age=2.0, gender='m'
6. care='c', age=3.0, gender='m'
7. care='a', age=3.0, gender='f'
8. care='b', age=3.0, gender='f'
  

тогда распределение gender в отношении care='a' возвращало бы что-то вроде

{'m:2, 'f':1}

Кажется, я не могу получить правильный синтаксис / понимание

Я использую python

Спасибо!

Ответ №1:

Глядя на ваш вопрос, я придумал приведенное ниже сопоставление, запрос и ответ.

Отображение

 PUT medicalrecord
{
  "mappings": {
    "mydocs": {
      "properties": {
        "diagnosis": {
          "type": "text"
        },
        "vignette": {
          "type": "text"
        },
        "symptoms": {
          "type": "text"
        },
        "care": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "age": {
          "type": "integer"
        },
        "gender":{
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}
  

Обратите внимание, как я создал несколько полей для gender и care . Я бы посоветовал вам перейти по этой ссылке, чтобы вы узнали о ее актуальности.

Запрос

Приведенный ниже запрос — это то, что вы ищете.

Это комбинация простого фильтра с использованием Bool запроса на care , за которым следует агрегирование терминов по полю gender .

 POST medicalrecord/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": {
        "term": {
          "care.keyword": "a"
        }
      }
    }
  },
  "aggs": {
    "mf_distribution": {
      "terms": {
        "field": "gender.keyword"
      }
    }
  }
}
  

Обратите внимание, что я создал запрос на care наличие значения a . Вы можете создавать аналогичные запросы для других его значений.

Глядя на ваш вопрос, я полагаю, что вы только начинаете с Elasticsearch. Я бы посоветовал вам потратить некоторое время на чтение о агрегациях.

Ниже показано, как будет выглядеть ваш ответ на приведенный выше запрос.

Ответ

 {
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "mf_distribution" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "m",
          "doc_count" : 2
        },
        {
          "key" : "f",
          "doc_count" : 1
        }
      ]
    }
  }
}
  

То, что вы хотите, можно увидеть в разделе buckets .

Надеюсь, это поможет!

Комментарии:

1. Я доберусь до этого как можно скорее, протестирую, затем приму. Спасибо. Я не знал, с чего начать чтение документа, и вы дали мне несколько советов

2. привет, @Gulzar, это было полезно. Решило ли это то, что вы искали?