2

When I use the "fields" option of a query I get a separate array for each field. Is it possible to get back the "complete" nested objects rather than just the field?

In the following example if I try to do "fields": ["cast"] it tells me that cast is not a leaf node. And if I do "fields": ["cast.firstName", "cast.middleName", "cast.lastName"] it returns 3 arrays.

Is there another way of retrieving just a partial amount of the document? Or is there a way to "reassemble" the separate fields into a complete "cast" object?

Example Index and Data:

POST /movies
{
   "mappings": {
      "movie": {
         "properties": {
            "cast": {
               "type": "nested"
            }
         }
      }
   }
}

POST /movies/movie
{
   "title": "The Matrix",
   "cast": [
      {
         "firstName": "Keanu",
         "lastName": "Reeves",
         "address": {
            "street": "somewhere",
            "city": "LA"
         }
      },
      {
         "firstName": "Laurence",
         "middleName": "John",
         "lastName": "Fishburne",
         "address": {
            "street": "somewhere else",
            "city": "NYC"
         }
      }
   ]
}

Example Query:

GET /movies/_search
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
            "nested": {
               "path": "cast",
               "filter": {
                  "bool": {
                     "must": [
                        { "term": { "firstName": "laurence"} },
                        { "term": { "lastName": "fishburne"} }
                     ]
                  }
               }
            }
         }
      }
   },
   "fields": [
      "cast.address.city",
      "cast.firstName",
      "cast.middleName",
      "cast.lastName"
   ]
}

Result of example query:

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "movies",
            "_type": "movie",
            "_id": "AU1JeyBseLgwMCOuOLsZ",
            "_score": 1,
            "fields": {
               "cast.firstName": [
                  "Keanu",
                  "Laurence"
               ],
               "cast.lastName": [
                  "Reeves",
                  "Fishburne"
               ],
               "cast.address.city": [
                  "LA",
                  "NYC"
               ],
               "cast.middleName": [
                  "John"
               ]
            }
         }
      ]
   }
}

1 Answer 1

5

I think this is what you're looking for:

POST /movies/_search
{
  "_source": {
    "include": [
      "cast.address.city",
      "cast.firstName",
      "cast.middleName",
      "cast.lastName"
    ]
  },
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "nested": {
          "path": "cast",
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "firstName": "laurence"
                  }
                },
                {
                  "term": {
                    "lastName": "fishburne"
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

Result:

{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "movies",
            "_type": "movie",
            "_id": "AU1PIJgBA_0Cyshym7-m",
            "_score": 1,
            "_source": {
               "cast": [
                  {
                     "lastName": "Reeves",
                     "address": {
                        "city": "LA"
                     },
                     "firstName": "Keanu"
                  },
                  {
                     "middleName": "John",
                     "lastName": "Fishburne",
                     "address": {
                        "city": "NYC"
                     },
                     "firstName": "Laurence"
                  }
               ]
            }
         }
      ]
   }
}

You can also choose to exclude fields instead of including or both, see documentation here: http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.