MST

星途 面试题库

面试题:ElasticSearch搜索API深度优化及复杂场景应用

在一个大型电商ElasticSearch集群中,索引包含海量商品数据,有各种复杂的搜索需求,如商品名称模糊匹配、按品牌过滤、按价格区间筛选、热门商品优先展示等。请详细描述如何综合运用搜索API,从索引结构设计、查询语句优化、缓存策略等多个维度,来实现高效且精准的搜索,以应对高并发的搜索请求。
41.5万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试

索引结构设计

  1. 字段类型选择
    • 对于商品名称字段,使用text类型,以支持全文搜索和模糊匹配。同时,可以为该字段增加keyword子字段,用于精确匹配,例如在根据商品ID查询时使用。
    • 品牌字段使用keyword类型,因为品牌通常是固定的有限集合,适合精确过滤。
    • 价格字段使用floatinteger类型(根据实际价格精度需求),以便进行范围查询。
  2. 多字段和分词器
    • 商品名称使用合适的分词器,如ik_max_word(针对中文),将文本拆分成尽可能多的词语,提高模糊匹配的召回率。
    • 对于一些需要特殊处理的字段,可设置多字段。比如商品描述,除了使用默认分词器进行全文搜索的text类型字段外,还可创建一个使用keyword类型的字段,用于存储原始描述内容,方便在特定场景下的精确检索。
  3. 索引分片与副本
    • 根据集群规模和数据量合理设置分片数量,以确保数据均匀分布,提高查询并行度。一般原则是每个分片大小不超过50GB - 100GB。例如,对于1TB的数据,可以设置10 - 20个分片。
    • 配置适当的副本数量,以提高系统的可用性和读性能。但副本过多会占用额外的磁盘空间和网络资源,一般设置1 - 2个副本。

查询语句优化

  1. 布尔查询组合
    • 使用bool查询来组合各种查询条件。例如,对于“商品名称模糊匹配且按品牌过滤且按价格区间筛选”的需求,可将商品名称的模糊查询放在should子句(以提高召回率),品牌过滤和价格区间筛选放在filter子句(提高查询效率,因为filter子句不会计算相关性分数且可利用缓存)。
    • 示例查询:
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "product_name": {
                            "query": "手机",
                            "fuzziness": "AUTO"
                        }
                    }
                }
            ],
            "filter": [
                {
                    "term": {
                        "brand": "华为"
                    }
                },
                {
                    "range": {
                        "price": {
                            "gte": 1000,
                            "lte": 5000
                        }
                    }
                }
            ]
        }
    }
}
  1. 排序优化
    • 对于热门商品优先展示,可通过在文档中增加一个表示热度的字段(如popularity),并在查询时按该字段降序排序。如果热度计算涉及复杂逻辑,可定期更新热度字段的值。
    • 示例排序:
{
    "query": {
        "match_all": {}
    },
    "sort": [
        {
            "popularity": {
                "order": "desc"
            }
        }
    ]
}
  1. 使用profile API
    • 在开发和调优阶段,利用profile API来分析查询性能,找出查询执行过程中的瓶颈,例如哪个分片、哪个阶段耗时较长,进而针对性地优化查询语句。

缓存策略

  1. 请求缓存
    • 启用Elasticsearch的请求缓存,对于相同的查询请求,直接从缓存中返回结果,减少重复查询压力。请求缓存适用于那些不经常变化的数据查询,如商品基本信息查询。可以通过设置request_cache.enabletrue来启用,并根据业务场景调整缓存的过期时间。
  2. 分片缓存
    • 分片缓存主要用于filter子句中的查询,Elasticsearch会自动缓存filter子句的结果。合理利用这一点,将一些不经常变化且可复用的过滤条件放在filter子句中,如品牌过滤、固定价格区间过滤等,以提高查询效率。
  3. 应用层缓存
    • 在应用层(如Web服务器)实现缓存机制,例如使用Redis。对于一些热门搜索关键词的结果进行缓存,当用户再次发起相同搜索请求时,直接从应用层缓存中返回结果,减少对Elasticsearch集群的请求压力。可以设置合适的缓存过期时间,以保证数据的实时性。同时,采用缓存更新策略,当商品数据发生变化时,及时更新应用层缓存。