Filter aggregations for nested documents


(Kaleem Ullah) #1

I've below nested mappings:

PUT /store
{
  "mappings": {
    "product": {
      "properties": {
        "specs": {
          "type": "nested",
          "properties": {
            "key": {
              "type": "string",
              "index": "not_analyzed"
            },
            "value": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}

POST /store/product/1
{
  "name": "Galaxy S4",
  "manufacturer": "Samsung",
  "type": "phone",
  "specs": [
    {
      "key": "os",
      "value": "Android"
    },
    {
      "key": "core",
      "value": 4
    },
    {
      "key": "ram",
      "value": "2GB"
    }
  ]
}

POST /store/product/2
{
  "name": "iPhone 5",
  "manufacturer": "Apple",
  "type": "phone",
  "specs": [
    {
      "key": "os",
      "value": "iOS"
    },
    {
      "key": "core",
      "value": 2
    },
    {
      "key": "ram",
      "value": "1GB"
    }
  ]
}

POST /store/product/3
{
  "name": "WF210ANW/XAA",
  "manufacturer": "Samsung",
  "type": "washing-machine",
  "specs": [
    {
      "key": "capacity",
      "value": 3.5
    },
    {
      "key": "loadType",
      "value": "front"
    },
    {
      "key": "presets",
      "value": 6
    }
  ]
}

POST /store/product/4
{
  "name": "WT4801CW",
  "manufacturer": "LG",
  "type": "washing-machine",
  "specs": [
    {
      "key": "capacity",
      "value": 3.7
    },
    {
      "key": "loadType",
      "value": "top"
    },
    {
      "key": "presets",
      "value": 9
    }
  ]
}

GET /store/_search?search_type=count
{
  "aggs": {
    "specs": {
      "nested": {
        "path": "specs"
      },
      "aggs": {
        "key": {
          "terms": {
            "field": "specs.key"
          },
          "aggs": {
            "value": {
              "terms": {
                "field": "specs.value"
              }
            }
          }
        }
      }
    }
  }
}

My question is if a user select 'android' from OS bucket then how can I filter other buckets i.e 'Core' and 'RAM' for 'android' option? and also 'ios' should also stay in OS bucket so that user can change search option when he needs to.

Thank you.


(Dariusp) #2

you should specify filters for each aggregations:

{
  "aggs": {
    "agg_os-filtered": {
      "filter": {
        "terms": {
          "core": [
            "2"
          ]
        }
      },
      "aggregations": {
        "agg_os": {
          "terms": {
            "field": "os"
          }
        }
      }
    }
  }
}

(Kaleem Ullah) #3

Thanks @Dariusp but it does not work because fields are dynamic and we really don't know field name to filter and aggregate. As you can see in my question, aggregations are being defined as:

  "aggs": {
    "key": {
      "terms": {
        "field": "specs.key"
      }
   }

So, all the specs keys will be aggregate.


(system) #4