面试题答案
一键面试索引结构设计
- 字段类型定义:
- 商品名称:使用
text
类型,并配置合适的分词器,如ik_smart
用于中文模糊搜索,同时可以增加keyword
子字段用于精确匹配。例如:
"product_name": { "type": "text", "analyzer": "ik_smart", "fields": { "keyword": { "type": "keyword" } } }
- 品牌:使用
keyword
类型,因为品牌通常不需要分词,用于精确过滤。
"brand": { "type": "keyword" }
- 价格:使用
float
或integer
类型(根据价格精度需求),用于价格区间过滤。
"price": { "type": "float" }
- 销量:使用
integer
类型,用于按销量排序。
"sales": { "type": "integer" }
- 评分:使用
float
类型,用于按评分排序。
"rating": { "type": "float" }
- 商品名称:使用
- 索引设置:合理设置
number_of_shards
和number_of_replicas
,根据数据量和服务器资源来确定。例如,对于数据量较大的情况,可以设置多个分片来提高并行处理能力。{ "settings": { "number_of_shards": 3, "number_of_replicas": 1 } }
查询逻辑实现
- 模糊搜索商品名称:使用
match
查询。例如:{ "query": { "match": { "product_name": "搜索关键词" } } }
- 按品牌过滤:使用
term
查询。例如:{ "query": { "bool": { "filter": [ { "term": { "brand": "品牌名称" } } ] } } }
- 按价格区间过滤:使用
range
查询。例如,查询价格在100到200之间的商品:{ "query": { "bool": { "filter": [ { "range": { "price": { "gte": 100, "lte": 200 } } } ] } } }
- 按销量排序:在查询中添加
sort
字段。例如,按销量降序排序:{ "query": { "match_all": {} }, "sort": [ { "sales": { "order": "desc" } } ] }
- 按评分排序:类似按销量排序,修改
sort
字段为评分字段。例如,按评分降序排序:{ "query": { "match_all": {} }, "sort": [ { "rating": { "order": "desc" } } ] }
- 组合查询:使用
bool
查询将上述各种查询条件组合起来。例如,模糊搜索商品名称,同时按品牌过滤和按销量排序:{ "query": { "bool": { "must": [ { "match": { "product_name": "搜索关键词" } } ], "filter": [ { "term": { "brand": "品牌名称" } } ] } }, "sort": [ { "sales": { "order": "desc" } } ] }
可能遇到的问题和解决方案
- 性能问题:
- 问题:数据量增大后,查询性能下降。
- 解决方案:
- 合理设置索引分片和副本,确保负载均衡。
- 使用缓存,如 Redis,缓存热门查询结果。
- 对经常查询的字段创建合适的索引,例如对品牌、价格等过滤字段。
- 分词问题:
- 问题:模糊搜索结果不准确,分词不合理。
- 解决方案:
- 选择合适的分词器,如对于中文可以使用
ik_smart
或ik_max_word
,并根据业务需求调整分词策略。 - 对分词结果进行测试和优化,通过
_analyze
API 查看分词效果并进行调整。
- 选择合适的分词器,如对于中文可以使用
- 数据一致性问题:
- 问题:数据更新后,搜索结果不能及时反映最新数据。
- 解决方案:
- 了解 ElasticSearch 的刷新机制,合理设置刷新间隔。可以手动调用
_refresh
API 使数据尽快可见,但频繁刷新会影响性能。 - 使用异步更新机制,在数据更新后,通过消息队列等方式异步通知 ElasticSearch 进行数据更新,确保数据一致性的同时减少对业务系统的影响。
- 了解 ElasticSearch 的刷新机制,合理设置刷新间隔。可以手动调用