Elasticsearch — как запрашивать вложенные поля?

#elasticsearch #curl

#elasticsearch #curl

Вопрос:

Я создал индекс ES с помощью приведенной ниже команды:

 curl -XPUT -H "Content-Type: application/json" http://localhost:9200/nested_test?pretty=true -d '{"mappings": {"properties": {"name": {"type": "keyword"}, "related": {"type": "nested", "properties": {"name": {"type": "keyword"}, "count": {"type": "long"}}}}}}'
 

Что дало мне ответ:

 {
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "nested_test"
}
 

Затем я помещаю в него некоторые образцы данных:

 curl -XPUT -H "Content-Type: application/json" http://localhost:9200/nested_test/_doc/1?pretty=true -d '{"name": "php", "related": [{"name": "c#", "count": 6806}, {"name": "c", "count": 4080}, {"name": "java", "count": 9745}, {"name": "javascript", "count": 9141}]}'
 

Что дало мне ответ:

 {
  "_index" : "nested_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}
 

И затем я, наконец, попытался запросить его, используя следующую команду:

 curl -X GET http://localhost:9200/nested_test/_search?pretty=true -H 'Content-Type: application/json' -d '{"query": {"nested": {"path": "related", "query": {"match": {"related.name": "javascript"}}}}}'
 

И это дало мне следующий ответ:

 {
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.2039728,
    "hits" : [
      {
        "_index" : "nested_test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.2039728,
        "_source" : {
          "name" : "php",
          "related" : [
            {
              "name" : "c#",
              "count" : 6806
            },
            {
              "name" : "c",
              "count" : 4080
            },
            {
              "name" : "java",
              "count" : 9745
            },
            {
              "name" : "javascript",
              "count" : 9141
            }
          ]
        }
      }
    ]
  }
}
 

Когда я ожидал следующего вывода:

 {
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.2039728,
    "hits" : [
      {
        "_index" : "nested_test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.2039728,
        "_source" : {
          "name" : "php",
          "related" : [
            {
              "name" : "javascript",
              "count" : 9141
            }
          ]
        }
      }
    ]
  }
}
 

Может кто-нибудь указать, что я делаю неправильно?

Ответ №1:

Отличное начало!! Вам просто нужно запрашивать только вложенные внутренние обращения:

 curl -X GET http://localhost:9200/nested_test/_search?pretty=true -H 'Content-Type: application/json' -d '{
  "_source": {
     "_excludes": ["related"]
  },
  "query": {
    "nested": {
      "path": "related",
      "query": {
        "match": {
          "related.name": "javascript"
        }
      },
      "inner_hits": {}                   <--- add this
    }
  }
}'
 

Также обратите внимание, что я исключаю «связанное» поле из возврата в _source документе, потому что вы получите внутренние хиты, которые вам нужны в fields разделе (родственный _source ).