MST
星途 面试题库

面试题:ElasticSearch地理范围聚合:复杂场景处理

现有一个ElasticSearch索引,其中存储了全球各个城市的商业店铺信息,每个文档包含店铺的地理位置(经纬度)、类别、营业额等字段。要求通过地理范围聚合,获取距离指定中心点100公里内不同类别店铺的平均营业额,并且要考虑到不同地区店铺分布密度不同可能导致的偏差,你会如何设计查询?
40.0万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试
  1. 使用geo_distance聚合来筛选距离指定中心点100公里内的店铺
    • 在Elasticsearch查询中,使用aggs(聚合)部分来定义地理距离聚合。假设索引名为shops_index,文档类型为shop,指定中心点的经纬度为lonlat
    {
        "aggs": {
            "shops_within_100km": {
                "geo_distance": {
                    "field": "地理位置",
                    "origin": {
                        "lat": lat,
                        "lon": lon
                    },
                    "distance": "100km"
                },
                "aggs": {
                    "by_category": {
                        "terms": {
                            "field": "类别"
                        },
                        "aggs": {
                            "avg_revenue": {
                                "avg": {
                                    "field": "营业额"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
  2. 考虑不同地区店铺分布密度不同导致的偏差
    • 使用采样:可以在查询中添加size参数来限制返回的文档数量,进行采样。例如设置size: 1000,这样可以避免因数据量过大导致计算资源耗尽,同时也能在一定程度上代表整体数据。
    {
        "size": 1000,
        "aggs": {
            "shops_within_100km": {
                "geo_distance": {
                    "field": "地理位置",
                    "origin": {
                        "lat": lat,
                        "lon": lon
                    },
                    "distance": "100km"
                },
                "aggs": {
                    "by_category": {
                        "terms": {
                            "field": "类别"
                        },
                        "aggs": {
                            "avg_revenue": {
                                "avg": {
                                    "field": "营业额"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    • 加权平均:如果有关于店铺分布密度的额外信息,比如某个区域的权重,可以在计算平均营业额时使用加权平均。可以在文档中新增一个表示权重的字段weight,然后使用weighted_avg聚合。
    {
        "aggs": {
            "shops_within_100km": {
                "geo_distance": {
                    "field": "地理位置",
                    "origin": {
                        "lat": lat,
                        "lon": lon
                    },
                    "distance": "100km"
                },
                "aggs": {
                    "by_category": {
                        "terms": {
                            "field": "类别"
                        },
                        "aggs": {
                            "weighted_avg_revenue": {
                                "weighted_avg": {
                                    "value": {
                                        "field": "营业额"
                                    },
                                    "weight": {
                                        "field": "weight"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }