How to get all aggregations by avoiding 1 filter from the elasticsearch query

房东的猫 提交于 2019-12-12 04:59:25

问题


I have an elasticsearch query which gets aggregations from the query results. The aggregations work fine because if i select to get all dresses from "women fashion" category that are golden in color.

The aggregations are working fine as it only returns the color golden. But logically we need all the colors in that aggregation.

On the frontend filter we are directly showing records from the aggregations requests. Right now On the frontend when someone selects "golden" color, it drills down and removes all other color filters and only shows golden color.

We need to somehow avoid the color from the aggregations to show all the results.

{
    "size": 15,
    "from": 0,
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "must": [{
                        "match": {
                            "category": "women_fashion"
                        }
                    }, {
                        "nested": {
                            "path": "variations",
                            "query": {
                                "bool": {
                                    "must": [{
                                        "match": {
                                            "variations.color": "golden"
                                        }
                                    }]
                                }
                            }
                        }
                    }],
                    "should": null
                }
            }
        }
    },
    "aggs": {
        "brands": {
            "terms": {
                "size": 10,
                "field": "brand"
            }
        },
        "min_price": {
            "min": {
                "field": "price"
            }
        },
        "max_price": {
            "max": {
                "field": "price"
            }
        },
        "variations": {
            "nested": {
                "path": "variations"
            },
            "aggs": {
                "size": {
                    "terms": {
                        "size": 100,
                        "field": "variations.size"
                    }
                },
                "color": {
                    "terms": {
                        "size": 100,
                        "field": "variations.color"
                    }
                },
                "waist_size": {
                    "terms": {
                        "size": 100,
                        "field": "variations.waist_size"
                    }
                }
            }
        }
    }
}

My Mapping:

{
    "mappings": {
        "products": {
            "properties": {
                "variations": {
                    "type": "nested"
                }
            }
        }
    }
}

A sample document:

{
    "title": "100% Cotton Unstitched Suit For Men",
    "slug": "100-cotton-unstitched-suit-for-men",
    "price": 200,
    "sale_price": 0,
    "vendor_id": 32,
    "featured": 0,
    "viewed": 20,
    "stock": 4,
    "sku": "XXX-B",
    "rating": 0,
    "active": 1,
    "vendor_name": "vendor_name",
    "category": [
        "men_fashion",
        "traditional_clothing",
        "unstitched_fabric"
    ],
    "image": "imagename.jpg",
    "variations": [
        {
            "variation_id": "34",
            "stock": 5,
            "price": 200,
            "variation_image": "",
            "sku": "XXX-C",
            "size": "m",
            "color": "red"
        },
        {
            "variation_id": "35",
            "stock": 5,
            "price": 200,
            "variation_image": "",
            "sku": "XXX-D",
            "size": "l",
            "color": "red"
        }
    ]
}

After going through lots of documentation, there is something called a post-filter that can somehow solve this issue. I tried using it but its a bit complicated. Does anyone have any past experience with this.


MY Updated Query with global aggrgations: I have tried using global aggregations, but it now shows all the brands in elasticsearch, where as i want to show brands associated with products in that category.

{
    "size": 15,
    "from": 0,
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "must": [{
                        "match": {
                            "category": "women_fashion"
                        }
                    }, {
                        "nested": {
                            "path": "variations",
                            "query": {
                                "bool": {
                                    "must": [{
                                        "match": {
                                            "variations.color": "golden"
                                        }
                                    }]
                                }
                            }
                        }
                    }],
                    "should": null
                }
            }
        }
    },
    "aggs": {
        "all_brands" : {
            "global" : {},
            "aggs" : { 
                "brands": {
                    "terms": {
                        "size": 10,
                        "field": "brand"
                    }
                }
            }
        },
        "brands": {
            "terms": {
                "size": 10,
                "field": "brand"
            }
        },
        "min_price": {
            "min": {
                "field": "price"
            }
        },
        "max_price": {
            "max": {
                "field": "price"
            }
        },
        "variations": {
            "nested": {
                "path": "variations"
            },
            "aggs": {
                "size": {
                    "terms": {
                        "size": 100,
                        "field": "variations.size"
                    }
                },
                "color": {
                    "terms": {
                        "size": 100,
                        "field": "variations.color"
                    }
                },
                "waist_size": {
                    "terms": {
                        "size": 100,
                        "field": "variations.waist_size"
                    }
                }
            }
        }
    }
}

回答1:


From https://www.elastic.co/guide/en/elasticsearch/guide/current/_scoping_aggregations.html#_global_bucket:

Use "global" : {} in aggregation seem do the job.

If you need filter aggregation after that, use https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html.



来源:https://stackoverflow.com/questions/46463938/how-to-get-all-aggregations-by-avoiding-1-filter-from-the-elasticsearch-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!