索引设计思路
- 商品名称字段:
- 类型:使用
text
类型,因为商品名称主要用于全文搜索。例如,一件商品名称为“智能蓝牙无线耳机”,用户可能输入“耳机”“蓝牙耳机”等各种部分内容来搜索。
- 分词器:选择合适的分词器,对于中文可以使用
ik_smart
或 ik_max_word
分词器。ik_smart
分词较为粗粒度,如“智能蓝牙无线耳机”会被分成“智能”“蓝牙”“无线”“耳机”;ik_max_word
分词更细粒度,会生成更多的词项,如“智能”“蓝牙”“无线”“耳机”“智能蓝牙”“蓝牙无线”等,具体选择取决于业务场景和搜索需求。
- 品牌字段:
- 类型:使用
keyword
类型,品牌通常是精确匹配的,如“Apple”“华为”等,不需要分词。这样可以保证在搜索品牌时能进行精确查找,不会出现因分词导致匹配不准确的问题。
- 价格区间字段:
- 类型:使用
float
或 integer
类型(取决于价格精度),如果价格精确到小数点后两位,使用 float
类型更合适。例如,价格为 199.99
。对于价格区间搜索,可以利用 Elasticsearch 的范围查询功能。
高效查询语句编写
- 多条件组合查询:
- 使用
bool
查询来组合不同条件。bool
查询包含 must
(必须满足的条件)、should
(应该满足的条件)、must_not
(必须不满足的条件)等子句。
- 例如,当用户输入商品名称“耳机”,品牌“Apple”,价格区间
100 - 500
时,查询语句如下:
{
"query": {
"bool": {
"must": [
{
"match": {
"商品名称": "耳机"
}
},
{
"term": {
"品牌": "Apple"
}
},
{
"range": {
"价格": {
"gte": 100,
"lte": 500
}
}
}
]
}
}
}
- 在上述语句中,
match
用于商品名称的全文匹配,term
用于品牌的精确匹配,range
用于价格区间的匹配。must
子句表示这些条件都必须满足才能返回结果。
- 提高搜索性能的优化点:
- 索引优化:确保索引有合适的分片和副本设置。对于电商搜索场景,数据量较大时,可以适当增加分片数量以提高并行处理能力,但也要注意分片过多会增加管理成本和查询开销。副本主要用于提高可用性和读性能,可以根据实际的读写负载情况进行调整。
- 缓存:利用 Elasticsearch 的查询缓存机制,对于一些频繁查询且数据变化不频繁的场景,开启查询缓存可以显著提高查询性能。可以通过修改 Elasticsearch 配置文件来调整缓存相关参数,如
indices.queries.cache.size
来设置查询缓存的大小。
- 排序优化:如果查询结果需要按照价格等字段进行排序,尽量避免在高基数(大量不同值)字段上进行排序,因为这会增加排序的开销。如果必须排序,可以考虑对排序字段构建
fielddata
,但要注意 fielddata
会占用较多内存。例如,对于价格字段,可以在索引映射时设置 fielddata: true
,这样在排序时可以直接从内存中读取数据,提高排序效率。