Search code examples
javascriptmongodbelasticsearchmongoosemongoose-schema

How to return available filters along with search query in elastic search


Basically im pretty new to elastic search and need some help in querying. Also let me know if i need to make any changes to my MongoDB Schema

I want to know how do i search in elastic search which would give me available products based on query and filters available to filter

something like

{
  products: [{...}, {...}, ...],
  filters: [ ... ]
}

product Schema is

    {
      title: "...",
      description: "...",
      categoryId: ObjectId
      variants: [ variant1ID, variant2ID ],
     ... other miscellaneous stuff
   }

Variant Schema is

{
 product : objectId,
 image: ..,
 price: ..., 
 attributes:[
   "SIZE-XL", // note: these are facetId , i can popuplate these to {name:"SIZE", value:"XL"}
   "COLOR-BLUE",
    ....and so on
 ]
}

First i taught to retrive filters based on category, because each category has a fixed number of facets , then i realiased , search query doesnt really have to be specific to category,

Also i am thinking to store product in elastic in below format

 { 
     productId: "...",
     title:"..",
     description: "...",
     categoryId: "....",
     image: "..",
     variantId:"..."
     price:"..",
     attributes: [
     {
      name:"SIZE",
      value:"XL",
     },
     {
      name:"COLOR",
      value:"BLUE",
     }
      .
      .
      .
      ]
}

basically storing each variant as seperately with its product title and description, So searching is fast and easier


Solution

  • You are right. In Elasticsearch you want to avoid using populate/joins and you look for flattening/de-normalizing your data.

    You can read this article to have a better idea about modeling variants:

    https://www.elastic.co/blog/how-to-create-a-document-schema-for-product-variants-and-skus-for-your-ecommerce-search-experience

    You can create a query that returns facets of every any you need, as long as a keyword type of that field exists (by default it does).

    https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html

    Then you can run a filter query:

    https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html#filter-context

    You want to use a "terms" query inside your filters because in most cases filters are exact matches (a checkbox in the UI) so this is the most efficient way to do it:

    https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html