1

This is data sample that I have in my index:

[{
  "filters": [
    {
      "group": "color",
      "attribute": "red"
    },
    {
      "group": "category",
      "attribute": "office"
    },
    {
      "group": "vendor",
      "attribute": "some vendor"
    },
    {
      "group": "sub category",
      "attribute": "tables"
    },
    {
      "group": "material",
      "attribute": "wood"
    }
  ],
  "image": "img",
  "itemId": "id"
},
{
  "filters": [
    {
      "group": "color",
      "attribute": "green"
    },
    {
      "group": "category",
      "attribute": "office"
    },
    {
      "group": "vendor",
      "attribute": "some vendor"
    },
    {
      "group": "sub category",
      "attribute": "tables"
    }
  ],
  "image": "img",
  "itemId": "id"
},
{
  "filters": [
    {
      "group": "color",
      "attribute": "brown"
    },
    {
      "group": "category",
      "attribute": "office"
    },
    {
      "group": "vendor",
      "attribute": "some vendor"
    },
    {
      "group": "sub category",
      "attribute": "chairs"
    },
    {
      "group": "style",
      "attribute": "modern"
    }
  ],
  "image": "img",
  "itemId": "id"
}]

Example of my query:

{
  "size": 48,
  "sort": [
    {
      "sequence": {
        "order": "asc"
      }
    }
  ],
  "aggs": {
    "price": {
      "range": {
        "field": "salePrice",
        "ranges": [
          {
            "to": 50.0
          },
          {
            "from": 50.0,
            "to": 100.0
          },
          {
            "from": 100.0,
            "to": 250.0
          },
          {
            "from": 250.0,
            "to": 500.0
          },
          {
            "from": 500.0,
            "to": 750.0
          },
          {
            "from": 750.0,
            "to": 1000.0
          },
          {
            "from": 1000.0,
            "to": 1500.0
          },
          {
            "from": 1500.0,
            "to": 2000.0
          },
          {
            "from": 2000.0,
            "to": 2500.0
          },
          {
            "from": 2500.0,
            "to": 3000.0
          },
          {
            "from": 3000.0,
            "to": 3500.0
          },
          {
            "from": 3500.0
          }
        ]
      }
    },
    "filters": {
      "nested": {
        "path": "filters"
      },
      "aggs": {
        "groups": {
          "terms": {
            "field": "filters.group"
          },
          "aggs": {
            "attributes": {
              "terms": {
                "field": "filters.attribute"
              }
            }
          }
        }
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "searchPattern": {
              "query": "chairs",
              "operator": "and"
            }
          }
        }
      ],
      "filter": [
        {
          "nested": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "filters.group": {
                        "value": "sub category"
                      }
                    }
                  },
                  {
                    "term": {
                      "filters.attribute": {
                        "value": "tables"
                      }
                    }
                  }
                ]
              }
            },
            "path": "filters",
            "_name": "filters"
          }
        }
      ]
    }
  }
} 

As you can see, here I do double aggregation for nested "filters" array, then do filtration and I receive such data:

category:
    office(3)
color:
    red(1)
    green(1)
    brown(1)
sub category:
    tables(2)
........

And it's logical, because I do filtration and only then do aggregation. But I want to get other sub categories and show there count. So, if user selects several attributes in one group, I want to do Or filtering. If selects attribute in another group, wanna do and filtering. Like so:

{
  "size": 48,
  "sort": [
    {
      "sequence": {
        "order": "asc"
      }
    }
  ],
  "aggs": {
    "price": {
      "range": {
        "field": "salePrice",
        "ranges": [
          {
            "to": 50.0
          },
          {
            "from": 50.0,
            "to": 100.0
          },
          {
            "from": 100.0,
            "to": 250.0
          },
          {
            "from": 250.0,
            "to": 500.0
          },
          {
            "from": 500.0,
            "to": 750.0
          },
          {
            "from": 750.0,
            "to": 1000.0
          },
          {
            "from": 1000.0,
            "to": 1500.0
          },
          {
            "from": 1500.0,
            "to": 2000.0
          },
          {
            "from": 2000.0,
            "to": 2500.0
          },
          {
            "from": 2500.0,
            "to": 3000.0
          },
          {
            "from": 3000.0,
            "to": 3500.0
          },
          {
            "from": 3500.0
          }
        ]
      }
    },
    "filters": {
      "nested": {
        "path": "filters"
      },
      "aggs": {
        "groups": {
          "terms": {
            "field": "filters.group"
          },
          "aggs": {
            "attributes": {
              "terms": {
                "field": "filters.attribute"
              }
            }
          }
        }
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "searchPattern": {
              "query": "chairs",
              "operator": "and"
            }
          }
        }
      ],
      "filter": [
        {
          "nested": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "filters.group": {
                        "value": "Category"
                      }
                    }
                  },
                  {
                    "bool": {
                      "should": [
                        {
                          "term": {
                            "filters.attribute": {
                              "value": "Decor"
                            }
                          }
                        },
                        {
                          "term": {
                            "filters.attribute": {
                              "value": "Patio Dining"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            },
            "path": "filters",
            "_name": "filters"
          }
        },
        {
          "nested": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "filters.group": {
                        "value": "Type"
                      }
                    }
                  },
                  {
                    "term": {
                      "filters.attribute": {
                        "value": "Coverlets"
                      }
                    }
                  }
                ]
              }
            },
            "path": "filters",
            "_name": "filters"
          }
        }
      ]
    }
  }
}

But, of course, this query has the same problem. So, is it possible to solve the problem in ElasticSearch? I found few words about post_filter, but have no ideas how to use it and how it can helps me, because I need to recalculate group attributes each time. Is it possible or I need to "store" group attributes anywhere and show them after each aggregation?

Alex Gurskiy
  • 346
  • 1
  • 7
  • 20
  • This answer might help: http://stackoverflow.com/questions/41369749/elasticsearch-generic-facets-structure-calculating-aggregations-combined-wit – Val Jan 13 '17 at 04:09
  • Yes, thanks. Already figured out by myself. Will post answer soon. – Alex Gurskiy Jan 13 '17 at 15:02

0 Answers0