Возврат только элементов массива в объекте, которые содержат определенное значение - PullRequest
1 голос
/ 03 апреля 2020

У меня есть следующий документ в поисковом индексе elasti c:

{
    "type": "foo",
    "components": [{
            "id": "1234123", ,
            "data_collections": [{
                    "date_time": "2020-03-02T08:14:48+00:00",
                    "group": "1",
                    "group_description": "group1",
                    "measures": [{
                            "measure_name": "MEASURE_1",
                            "actual": "23.34"
                        }, {
                            "measure_name": "MEASURE_2",
                            "actual": "5"
                        }, {
                            "measure_name": "MEASURE_3",
                            "actual": "string_message"
                        }, {
                            "measure_name": "MEASURE_4",
                            "actual": "another_string"
                        }
                    ]
                },
                {
                    "date_time": "2020-03-03T08:14:48+00:00",
                    "group": "2",
                    "group_description": "group2",
                    "measures": [{
                            "measure_name": "MEASURE_1",
                            "actual": "23.34"
                        }, {
                            "measure_name": "MEASURE_4",
                            "actual": "foo"
                        }, {
                            "measure_name": "MEASURE_5",
                            "actual": "bar"
                        }, {
                            "measure_name": "MEASURE_6",
                            "actual": "4"
                        }
                    ]
                }
            ]
        }
    ]
}

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

Например, я ищу документы с "group": "1" и "measure_name": "MEASURE_", и результат, который я хотел бы получить, выглядит следующим образом:

{
    "_id": "oiqwueou8931283u12",
    "_source": {
        "type": "foo",
        "components": [{
                "id": "1234123", ,
                "data_collections": [{
                        "date_time": "2020-03-02T08:14:48+00:00",
                        "group": "1",
                        "group_description": "group1",
                        "measures": [{
                                "measure_name": "MEASURE_1",
                                "actual": "23.34"
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

Я думаю, что получится близко к тому, что я ищу, это параметр source, но, насколько я знаю, нет способа отфильтровать такие значения, как {"measure_name": {"value": "MEASURE_1"}}

Спасибо.

1 Ответ

2 голосов
/ 03 апреля 2020

Самое простое сопоставление, которое приходит на ум, это

PUT timo
{
  "mappings": {
    "properties": {
      "components": {
        "type": "nested",
        "properties": {
          "data_collections": {
            "type": "nested",
            "properties": {
              "measures": {
                "type": "nested"
              }
            }
          }
        }
      }
    }
  }
}

, а поисковый запрос будет

GET timo/_search
{
  "_source": ["inner_hits", "type", "components.id"], 
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "components.data_collections",
            "query": {
              "term": {
                "components.data_collections.group.keyword": {
                  "value": "1"
                }
              }
            },
            "inner_hits": {}
          }
        },
        {
          "nested": {
            "path": "components.data_collections.measures",
            "query": {
              "term": {
                "components.data_collections.measures.measure_name.keyword": {
                  "value": "MEASURE_1"
                }
              }
            },
            "inner_hits": {}
          }
        }
      ]
    }
  }
}

Обратите внимание на параметр inner_hits в каждом подзапросе и что параметр _source ограничен, поэтому мы не возвращаем хит целом , а только те подгруппы, которые действительно совпадают. type и component.id нельзя «увидеть» во вложенных полях, поэтому мы включили их явно.

Тогда ответ должен выглядеть следующим образом: enter image description here

Теперь у вас есть именно те атрибуты, которые вам нужны, поэтому небольшая постобработка даст вам нужный формат!


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

...