elasticsearch实现优先展示连词并按某个字段折叠显示最新一条
前言
场景要求:
- 优先展示关键词连词的商品
- 按照某个字段折叠相同字段,并按指定排序字段选择第一个
match_phrase 顺序前缀 + boost 权重
elasticsearch常用匹配:
match_phrase 查询
match_phrase 查询用于匹配包含短语的文档,它会确保查询的短语在文档中按顺序连续出现。
{
"query": {
"match_phrase": {
"content": "星球大战"
}
}
}
multi_match 查询
multi_match 查询允许在多个字段上执行相同的查询,可以指定不同的字段权重和查询类型。
{
"query": {
"multi_match": {
"query": "星球大战",
"fields": ["title", "content^2"],
"type": "best_fields",
"tie_breaker": 0.3
}
}
}
match_all 查询
match_all 查询会匹配所有文档,常用于返回整个索引的内容或与其他查询一起使用。
{
"query": { "match_all": {}
}
}
match_none 查询
match_none 查询用于不匹配任何文档,通常用于测试或特定的过滤场景。
{
"query": {
"match_none": {}
}
}
bool 查询
bool 查询是一个复合查询,允许将多个查询条件组合在一起,包括 must 、 should 、 must_not 和 filter 子句。
{
"query": {
"bool": {
"must": [
{ "match": { "title": "星球" } },
{ "match": { "title": "大战" } }
],
"filter": [
{ "range": { "price": { "gte": 100, "lte": 200 } } }
]
}
}
}
term 查询
term 查询用于精确匹配某个字段的值,不会对查询字符串进行分析。
{
"query": {
"term": {
"category.keyword": "电影"
}
}
}
terms 查询
terms 查询用于匹配多个值,类似于 SQL 中的 IN 操作符。
{
"query": {
"terms": {
"tags.keyword": ["science fiction", "action"] }
}
}
efix 查询
prefix 查询用于匹配指定字段开头的文档。
{
"query": {
"prefix": {
"title": "星球"
}
}
}
wildcard 查询
wildcard 查询允许使用通配符匹配字段值。
{
"query": {
"wildcard": {
"title": "星球*"
}
}
}
range 查询
range 查询用于匹配指定范围内的字段值。
{
"query": {
"range": {
"price": {
"gte": 100,
"lte": 200
}
}
}
}
要实现目标效果,这里需要用的就是match_phrase 顺序前缀 + boost 权重
查询按顺序的与不按顺序的,将按顺序的权重高于不按顺序的就可以了
"query": {
"bool": {
"should": [
{
"match_phrase": {
"name": {
"query": "星球大战",
"boost": 3 # 权重
}
}
},
{
"match": {
"name": {
"query": "星球大战",
"boost": 1 # 权重
}
}
}
]
}
},
collapse 折叠
Elasticsearch (ES) 中的collapse
功能主要用于在搜索结果中进行字段折叠,以便于根据某个字段的不同值只返回每个值的首个匹配项。这类似于SQL 中的 GROUP BY
功能,但在 Elasticsearch 中主要用于避免返回重复的数据,并集中展示多样化的结果。这个功能特别适用于想要从每个类别或组获取顶部记录
的场景。
基本用法
基本的 collapse 语法需要指定一个字段,搜索结果会根据该字段的值折叠,每个不同的值只返回第一条匹配的记录。例如,如果你有一个包含多个产品信息的索引,每个产品都有一个 “brand” 字段,你可能想要从每个品牌中获取一条记录。
GET /products/_search
{
"query": {
"match_all": {}
},
"collapse": {
"field": "brand.keyword" // 使用.keyword后缀以确保字段不分词
}
}
在这个示例中,搜索将返回每个品牌的第一个产品。
高级功能
如果你希望除了获取每个分组的首个匹配项外,还想获取每个分组的更多记录,可以使用 inner_hits 选项。例如,获取每个品牌的前三个产品:
GET /products/_search
{
"query": {
"match_all": {}
},
"collapse": {
"field": "brand.keyword",
"inner_hits": {
"name": "more_products", // inner hits的名称,可自定义
"size": 3 // 每个品牌返回的记录数
}
}
}
排序
你也可以在折叠字段上指定排序规则,以确定哪条记录应该作为每个值的代表:
GET /products/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {
"order": "asc"
}
}
],
"collapse": {
"field": "brand.keyword"
}
}
在这个例子中,系统会针对每个品牌返回价格最低的产品。
注意事项
性能影响:使用 collapse 可能会影响查询的性能,尤其是在处理大量数据时。
字段选择:折叠字段应该是非分析字段(例如,通常带有 .keyword 后缀的字段),以保证字段值的完整性。
限制:折叠操作不能和某些其他特性如聚合(aggregations)直接组合。
通过适当使用 collapse 功能,可以在 Elasticsearch 中有效地管理和优化搜索结果的展示,使得结果更加精准和高效。