In Part 1 of this series we described the faceted search/navigation search pattern with an example from the northface.com website. We also installed Elasticsearch and Kibana. In this post we’ll be setting up the index, define the data structure, create a mapping document, load some sample data and construct a query for faceted search/navigation.
Creating the Index
To store and index data in elasticsearch we first need to create an index. The index can have specific settings associated with it and can be defined in the body of the request. We will set the number_of_shards and number_of_replicas to 1 for simplicity and to avoid an issue where the result item scores can be incorrect with multiple shards and very small dataset.
Defining the data structure
We have a concept of the Product which describes the product being sold. It has a Product Id, Name, Description, Image, Specifications, etc. The product may come in different variations, for example color or sizes in case of clothing products. A variation is represented by Variant entity. A Variant is what is actually inventoried, sold, and shipped when a customer purchases a product. It has a SKU, Price, Stock, Variant Image and other Variant specific attributes (color, size, etc.) associated with it. In our NorthFace.com example from Part 1, we performed a faceted search for Red and Orange Jackets and the results came back with the images showing the appropriate colors. To be able to achieve this we need to index the Variants instead of the Products. Doing this brings up a problem though. Now if you searched for Jacket without the color facet selected you will get all Variants for a Product showing up in the results. This is not an ideal experience but thankfully there is a way to fix it which I’ll describe shortly.
The following Product->Variants structure represents a Color-Size attribute combination typical of a clothing product.
Product: Men’s Venture 2 Jacket
- Variant: Red-Small
- Variant: Red-Medium
- Variant: Red-Large
- Variant: Blue-Small
- Variant: Blue-Medium
- Variant: Blue-Large
- Variant: Yellow-Small
- Variant: Yellow-Medium
- Variant: Yellow-Large
A JSON representation of such a hierarchy would look something like this: