Using nested objects

Nested objects can come in handy in certain situations. Basically, with nested objects, ElasticSearch allows us to connect multiple documents together—one main document and multiple dependent ones. Now, imagine that we have a shop with clothes and we store the size and color of each T-shirt. Our standard, non-nested mappings could look like the following code (stored in cloth.json):

{
 "cloth" : {
  "properties" : {
   "name" : {"type" : "string", "store" : "yes", "index" : "analyzed"},
   "size" : {"type" : "string", "store" : "yes", "index" : "not_analyzed"},
   "color" : {"type" : "string", "store" : "yes", "index" : "not_analyzed"}
  }
 }
}

Now imagine that we have a T-shirt in our shop that we only have in the XXL size in "red" and XL size in "black". So our example document could look like the following code:

{
 "name" : "Test shirt",
 "size" : [ "XXL", "XL" ],
 "color" : [ "red", "black" ]
}

But if one of our clients were to search our shop in order to find the XXL T-shirt in black, a query similar to the following one could be run:

curl -XGET 'localhost:9200/shop/cloth/_search?pretty=true' -d '{
 "query" : {
  "bool" : {
   "must" : [
    {
     "term" : { "size" : "XXL" }
    },
    {
     "term" : { "color" : "black" }
    }
   ]
  }
 }
}'

We should get no results right? But in fact ElasticSearch returned the following document:

{
  (…)
  "hits" : {
    "total" : 1,
    "max_score" : 0.2712221,
    "hits" : [ {
      "_index" : "shop",
      "_type" : "cloth",
      "_id" : "1",
      "_score" : 0.2712221, "_source" : { "name" : "Test shirt", "size" : [ "XXL", "XL" ], "color" : [ "red", "black" ]}
    } ]
  }
}

So, let's modify our mappings to use nested objects to separate color and size to different, nested documents (we store these mappings in the cloth_nested.json file):

{
 "cloth" : {
  "properties" : {
   "name" : {"type" : "string", "store" : "yes", "index" : "analyzed"},
   "variation" : {
    "type" : "nested",
    "properties" : {
     "size" : {"type" : "string", "store" : "yes", "index" : "not_analyzed"},
     "color" : {"type" : "string", "store" : "yes", "index" : "not_analyzed"}
    }
   }
  }
 }
}

As you can see, we've introduced a new object inside our cloth type, variation. This is a nested object (type property set to nested). It basically says that we will want to index nested documents. Now, let's modify our document to something like the following code:

{
 "name" : "Test shirt",
 "variation" : [
  { "size" : "XXL", "color" : "red" },
  { "size" : "XL", "color" : "black" }
 ]
}

We've structured the document so that each size and its matching color is a separate document. However, if you were to run our previous query, it wouldn't return any documents. This is because in order to query for nested documents, we need to use a specialized query. So now our query looks like this:

curl -XGET 'localhost:9200/shop/cloth/_search?pretty=true' -d '{
 "query" : {
  "nested" : {
   "path" : "variation",
   "query" : {
    "bool" : {
     "must" : [
      { "term" : { "variation.size" : "XXL" } },
      { "term" : { "variation.color" : "black" } }
     ]
    }
   }
  }
 }
}' 

And now, the preceding query wouldn't return the indexed document, because we don't have a nested document that has a size equal to XXL and color black.

Lastly, let's look at the query. As you can see, we've used the nested query in order to search in the nested documents. The path property specifies the name of the nested object (yes, we can have multiple objects). As you can see, we just included a standard query section under the nested type. Please also note that we specified the full path for the field names in the nested objects, which is handy when you have multi-level nesting, which is also possible.

Note

If you would like to use the nested type functionality as a filter, you can use it as there is a nested filter that has the same functionality as the nested query. Please refer to the Filtering your results section in Chapter 3, Extending Your Structure and Search, for information about filtering.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset