Skip to content

[Thank Goodness It’s Search]: Building bottom-up Faceted Navigation for Retail Catalogs: Part3 - reverse_nested queries in OpenSearch

4 minute read
Content level: Intermediate
1

This post offers a detailed, example-driven walk-through on building bottom-up faceted navigation that lets users to shift context from nested SKU variants back to root product level facets

Welcome to Thank Goodness It’s Search series—your Friday fix of OpenSearch learnings, feature drops, and real-world solutions. I will keep it short, sharp, and search-focused—so you can end your week a little more knowledge on Search than you started.

Today, Friday the 13th and the topic is: Building bottom-up Faceted Navigation for Retail Catalogs: reverse_nested queries in OpenSearch, how do we navigate through mysterious path, navigate backwards through product catalog hierarchies!

This article is the third installment in our series on building faceted navigation for retail catalogs using OpenSearch. In our previous post "Building top-down Faceted Navigation for Retail Catalogs", we covered creating top-down faceted navigation using a synthetic cosmetic product catalog. Today, we'll use that same dataset and index to explore building bottom-up faceted navigation using reverse_nested queries.

What is bottom-up faceted navigation?

Bottom-up faceted navigation allows users to start their search from specific product variants (like SKUs) and then navigate up to broader product categories. This is particularly useful in scenarios where users may know specific attributes of a product variant but want to explore related products or categories.

Understanding reverse_nested queries in OpenSearch

In OpenSearch, a reverse_nested aggregation allows you to move from a nested context back to the root document context. This is particularly useful when you have a nested field (like SKUs within a product) and you want to perform aggregations or filters based on the parent document (the product itself).

For example, if you've filtered down to SKUs where skuinfo.color = "Rose Petal", you're operating at the nested SKU level. But with reverse_nested, you can navigate through "Rose Petal lipstick thats Vegan".

Example Scenario: Navigating from SKU to Product Category

Let's say you want to find all products that have a SKU with a specific color variant, and then see which categories those products belong to. Execute this query and analyze how you can see a variant distributed across all subcategories.

GET /cosmetic-makeup-index/_search
{
  "size": 0,
    "query": {
    "match_all": {}
  },
  "aggs": {
    "variants": {
      "nested": {
        "path": "skuinfo"
      },
      "aggs": {
        "by_colr": {
          "terms": {
            "field": "skuinfo.color.keyword",
            "size": 10
          }, 
          "aggs": {
            "back_to_cat": {
              "reverse_nested": {},
              "aggs": {
                "group_by_cat": {
                  "terms": {
                    "field": "subcategory.keyword",
                    "size": 10
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Now, if I were to choose a specific color, say "Magenta", you can see the similar distribution of this color at parent level.

GET /cosmetic-makeup-index/_search
{
  "size": 0,
    "query": {
    "match_all": {}
  },
  "aggs": {
    "variants": {
      "nested": {
        "path": "skuinfo"
      },
      "aggs": {
        "by_colr": {
          
          "filter": {
            "term": {
              "skuinfo.color.keyword": "Magenta"
              
            }
          }, 
          "aggs": {
            "back_to_cat": {
              "reverse_nested": {},
              "aggs": {
                "by_cat": {
                  "terms": {
                    "field": "subcategory.keyword",
                    "size": 100
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Now, lets find all vegan products that have a SKU with a specific color variant. This is particularly useful for scenarios where you want to understand the broader context of products that contain specific SKUs, enabling improved findability.

GET /cosmetic-makeup-index/_search
{
  "size": 0,
    "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "subcategory.keyword": "Lipstick"
          }
        }
      ]
    }
  },
  "aggs": {
    "variants": {
      "nested": {
        "path": "skuinfo"
      },
      "aggs": {
        "by_colr": {
          
          "filter": {
            "term": {
              "skuinfo.color.keyword": "Magenta"
              
            }
          }, 
          "aggs": {
            "back_to_cat": {
              "reverse_nested": {},
              "aggs": {
                "by_axilogy_vegan": {
                  "filter": {
                    "term": {
                      "axiology.keyword": "Vegan"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Conclusion

In this article, we explored how to implement bottom-up faceted navigation using reverse_nested queries in OpenSearch. We learned:

  • How reverse_nested aggregations allow us to shift context from nested SKU level back to root product level
  • Examples of querying color variants across subcategories using nested and reverse_nested aggregations
  • Practical applications for enabling bottom-up navigation for retail catalogs

In the next post, we'll dive into how to use post_filter to fine-tune search results after aggregations are calculated—so you can keep your facets accurate while responding to user selections in real time.

See you next Friday with another search solution in the Thank Goodness It's Search series! Until then, happy searching! 🔍

Note: The dataset and index used in this article are synthetic and created for demonstration purposes only. They do not represent real products or brands.