Как вернуть только сопоставленный объект во вложенном поле, а не весь объект?

#elasticsearch

#elasticsearch

Вопрос:

Версия Elasticsearch ( bin/elasticsearch --version ): установлены плагины 5.6.11 :

Версия JVM ( java -version ): openjdk версии «1.8.0_222» Среда выполнения OpenJDK (сборка 1.8.0_222-8u222-b10-1ubuntu1 ~ 16.04.1-b10) 64-разрядная серверная виртуальная машина OpenJDK (сборка 25.222-b10, смешанный режим)

Версия ОС ( uname -a если на Unix-подобной системе): Linux myserver 4.4.0-131-generic #157-Ubuntu SMP Чт 12 июля 15:51:36 UTC 2018 x86_64 x86_64 x86_64 GNU / Linux

В настоящее время я пытаюсь предотвратить, если это возможно, создание другого индекса, и в результате я получил вопрос: как мне получить только сопоставленный элемент во вложенном объекте вместо всего объекта? в моем случае это: my_nested_field.my_object.name это соответствует моим критериям?

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

 {
  "my_super_special_index": {
    "aliases": {
      "my_super_special_index_alias": {}
    },
    "mappings": {
      "my_super_special_index": {
        "properties": {
          "my_nested_field": {
            "type": "nested",
            "properties": {
              "my_object": {
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "last_known_party": {
                    "type": "boolean"
                  },
                  "name": {
                    "type": "text",
                    "store": true,
                    "analyzer": "translation_index_analyzer",
                    "search_analyzer": "translation_search_analyzer"
                  },
                  "name_raw": {
                    "type": "keyword"
                  },
                }
              }
            }
          }
        }
      }
    }
  }
}
  

мой запрос:

 GET my_super_special_index/_search
{
  "_source": "my_nested_field",
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "my_nested_field",
            "query": {
              "bool": {
                "should": [
                  {
                    "match_phrase": {
                      "my_nested_field.my_object.name": {
                        "query": "my name"
                      }
                    }
                  },
                  {
                    "match": {
                      "my_nested_field.my_object.name": {
                        "query": "my name",
                        "boost": 100
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  },
  "size": 50
}
  

Что я получаю в результате :

 {
  "took": 8,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1337,
    "hits": [
      {
        "_index": "my_super_special_index",
        "_type": "my_super_special_index",
        "_score": 2433.0676,
        "_source": {
          "id": "4712182",
          "my_nested_fields": [
            {
              ...
              "my_object": [
                {
                  "id": "22222",
                  "name": "name i want",
                  "name_raw": "name i want",
                  "last_known_party": true
                },
                {
                  "id": "13333",
                  "name": "hiyoo definitely doesnt match",
                  "name_raw": "hiyoo definitely doesnt match",
                  "last_known_party": true
                }
              ],
              "my_other_object": [
                {
                  "id": "26672",
                  "name": "dont really like this",
                  "name_raw": "dont really like this",
                  "last_known_party": true
                }
              ]
            }
            ],
        }
      },
      
      {
        "_index": "my_super_special_index",
        "_type": "my_super_special_index",
        "_score": 2422.111,
        "_source": {
          "id": "357878",
          "my_nested_fields": [
            {
              ...
              "my_object": [
                {
                  "id": "661111",
                  "name": "ratatoille",
                  "name_raw": "ratatoille",
                  "last_known_party": true
                },
                {
                  "id": "2334",
                  "name": "name i want or close match",
                  "name_raw": "name i want or close match",
                  "last_known_party": true
                }
              ],
              "my_other_object": [
                {
                  "id": "63111",
                  "name": "ttttt ok 1337",
                  "name_raw": "ttttt ok 1337",
                  "last_known_party": true
                }
              ]
            }
            ],
        }
      }
  }
}
  

Что я хочу получить от ES:

 {
  "took": 8,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1337,
    "hits": [
      {
        "_index": "my_super_special_index",
        "_type": "my_super_special_index",
        "_score": 2433.0676,
        "_source": {
          "id": "4712182",
          "my_nested_fields": [
            {
              ...
              "my_object": [
                {
                  "id": "22222",
                  "name": "name i want",
                  "name_raw": "name i want",
                  "last_known_party": true
                }
              ]
            }
            ],
        }
      },
      
      {
        "_index": "my_super_special_index",
        "_type": "my_super_special_index",
        "_score": 2422.111,
        "_source": {
          "id": "357878",
          "my_nested_fields": [
            {
              ...
              "my_object": [
                {
                  "id": "2334",
                  "name": "name i want or close match",
                  "name_raw": "name i want or close match",
                  "last_known_party": true
                }
              ]
            }
            ],
        }
      }
  }
}
  

Заранее спасибо!

Ответ №1:

Вложенный inner_hist на помощь:

 GET my_super_special_index/_search
{
  "_source": "my_nested_field",
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "my_nested_field",
            "inner_hits": {},                        <--- add this
            "query": {
              "bool": {
                "should": [
                  {
                    "match_phrase": {
                      "my_nested_field.my_object.name": {
                        "query": "my name"
                      }
                    }
                  },
                  {
                    "match": {
                      "my_nested_field.my_object.name": {
                        "query": "my name",
                        "boost": 100
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  },
  "size": 50
}
  

Примечание: поскольку my_object это не nested так, вы все равно получите полный массив, но вы получите только my_nested_fields объект, а не my_other_object один.