唐山网站建设哪家好今天有什么新闻
文章目录
- 00. 数据准备
- 01. Elasticsearch 默认的排序方式是什么?
- 02. Elasticsearch 支持哪些排序方式?
- 03. ElasticSearch 如何指定排序方式?
- 04. ElasticSearch 如何按照相关性排序?
- 05. ElasticSearch 查询结果如何不按照相关性排序?
- 06. ElasticSearch 如何按照字段的值排序?
- 07. ElasticSearch 排序字段的类型?
- 08. ElasticSearch 如何对文本类型的字段进行排序?
- 09. ElasticSearch 如何按照多个字段排序?
- 10. EalsticSearch 如何实现分页排序?
- 11. SpringBoot整合ES实现:按相关度排序
- 12. SpringBoot整合ES实现:按字段值排序
- 13. SpringBoot整合ES实现:按文本类型字段排序
- 14. SpringBoot整合ES实现:按多字段值排序
00. 数据准备
PUT /my_index/_doc/1
{"title": "金都时尚情侣浪漫主题酒店","content": "青岛","price": 556
}PUT /my_index/_doc/2
{"title": "金都嘉怡假日酒店","content": "北京","price": 337
}PUT /my_index/_doc/3
{"title": "金都欣欣24小时酒店","content": "天津","price": 200
}PUT /my_index/_doc/4
{"title": "金都自如酒店","content": "上海","price": 300
}
01. Elasticsearch 默认的排序方式是什么?
ElasticSearch 默认的排序方式是相关性排序。相关性排序是根据查询条件与文档的匹配程度来计算每个文档的相关性得分,然后按照得分从高到低进行排序。相关性排序是 ElasticSearch 中最常用的排序方式,因为它可以根据查询条件与文档的匹配程度来确定文档的排序位置,从而提高查询结果的准确性。
在相关性排序中,ElasticSearch 使用一种称为 TF-IDF 的算法来计算每个查询条件与文档的匹配程度。TF-IDF 算法可以有效地确定查询条件与文档的匹配程度,从而计算出每个文档的相关性得分。具体来说,TF-IDF 算法会根据查询条件中每个词的词频(TF)和文档集合中包含该词的文档数的倒数(IDF)来计算每个查询条件与文档的匹配程度,然后将所有查询条件的匹配程度加权求和,得到文档的相关性得分。
需要注意的是,相关性排序并不一定是最优的排序方式,因为它只考虑了查询条件与文档的匹配程度,而没有考虑其他因素,例如文档的时间戳、文档的重要性等。在某些情况下,其他排序方式可能更适合。在这种情况下,可以通过在查询语句中指定排序方式来实现其他排序方式。
在 Elasticsearch 中, 相关性得分由一个浮点数进行表示,并在搜索结果中通过 _score
参数返回, 默认排序是 _score
降序:
POST /my_index/_search
{"query": {"match": {"title": "金都酒店"}}
}
{"took" : 2,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 4,"relation" : "eq"},"max_score" : 0.48362204,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "4","_score" : 0.48362204,"_source" : {"title" : "金都自如酒店","content" : "上海","price" : 300}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 0.4367569,"_source" : {"title" : "金都嘉怡假日酒店","content" : "北京","price" : 337}},{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : 0.41657305,"_source" : {"title" : "金都欣欣24小时酒店","content" : "天津","price" : 200}},{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.36585158,"_source" : {"title" : "金都时尚情侣浪漫主题酒店","content" : "青岛","price" : 556}}]}
}
02. Elasticsearch 支持哪些排序方式?
Elasticsearch 支持多种排序方式,包括按照相关度得分排序、按照字段值排序、按照多个字段排序等。
03. ElasticSearch 如何指定排序方式?
可以在查询语句中使用 “sort” 参数来指定排序方式,可以指定排序字段、排序方式等。
04. ElasticSearch 如何按照相关性排序?
默认情况下,Elasticsearch 会根据文档与查询的相关度得分进行排序,得分越高的文档排在越前面。
{"query": {"match": {"title": "金都酒店"}},"sort": [{"_score": {"order": "desc"}}]
}
{"took" : 4,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 4,"relation" : "eq"},"max_score" : 0.48362204,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "4","_score" : 0.48362204,"_source" : {"title" : "金都自如酒店","content" : "上海","price" : 300}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 0.4367569,"_source" : {"title" : "金都嘉怡假日酒店","content" : "北京","price" : 337}},{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : 0.41657305,"_source" : {"title" : "金都欣欣24小时酒店","content" : "天津","price" : 200}},{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.36585158,"_source" : {"title" : "金都时尚情侣浪漫主题酒店","content" : "青岛","price" : 556}}]}
}
05. ElasticSearch 查询结果如何不按照相关性排序?
Elasticsearch的过滤器(Filter)不会计算相关性得分,它们只是根据指定的条件来过滤文档,而不会影响文档的相关性得分。相比之下,查询(Query)会计算相关性得分,它们会根据查询条件来计算文档的相关性得分,并将得分作为文档的排序依据。因此,如果您需要根据相关性对文档进行排序,应该使用查询(Query)而不是过滤器(Filter)。
Elasticsearch的过滤器(Filter)可以用来过滤文档,以便于在查询时只返回符合条件的文档。以下是使用过滤器的一些常见方法:
使用布尔过滤器(Boolean Filter):布尔过滤器可以将多个过滤器组合起来,以实现复杂的过滤逻辑。例如,可以使用must、should、must_not等关键字来组合多个过滤器。
使用范围过滤器(Range Filter):范围过滤器可以根据指定的范围来过滤文档。例如,可以使用range关键字来指定字段的范围。
使用存在过滤器(Exists Filter):存在过滤器可以过滤出指定字段存在或不存在的文档。例如,可以使用exists关键字来指定字段是否存在。
使用缓存过滤器(Cache Filter):缓存过滤器可以将过滤结果缓存起来,以提高查询性能。例如,可以使用cache关键字来指定是否缓存过滤结果。
GET /my_index/_search
{"query": {"bool": {"should": [{"term": {"price": "300"}}]}}
}
06. ElasticSearch 如何按照字段的值排序?
Elasticsearch可以按照字段的值进行排序,可以使用sort参数来指定排序方式。
GET /my_index/_search
{"query": {"match_all": {}},"sort": [{"price": {"order": "asc"}}]
}
{"took" : 17,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 4,"relation" : "eq"},"max_score" : null,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : null,"_source" : {"title" : "金都欣欣24小时酒店","content" : "天津","price" : 200},"sort" : [200]},{"_index" : "my_index","_type" : "_doc","_id" : "4","_score" : null,"_source" : {"title" : "金都自如酒店","content" : "上海","price" : 300},"sort" : [300]},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : null,"_source" : {"title" : "金都嘉怡假日酒店","content" : "北京","price" : 337},"sort" : [337]},{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : null,"_source" : {"title" : "金都时尚情侣浪漫主题酒店","content" : "青岛","price" : 556},"sort" : [556]}]}
}
07. ElasticSearch 排序字段的类型?
在Elasticsearch中,排序字段的类型非常重要,因为不同类型的字段可能会导致排序结果不同。以下是一些常见的排序字段类型及其特点:
文本类型(text):文本类型的字段通常用于全文搜索,它们会被分词器处理成多个词条,因此在排序时可能会出现意外的结果。如果要按照文本类型的字段进行排序,通常需要使用keyword类型的子字段,或者使用fielddata特性来将文本类型的字段转换为可排序的类型(ES新版本不支持了)。
数字类型(numeric):数字类型的字段通常用于存储数字,它们可以按照数值大小进行排序。在Elasticsearch中,数字类型的字段包括整数类型(integer、long、short、byte)和浮点数类型(float、double)。如果要按照数字类型的字段进行排序,通常不需要进行额外的配置。
日期类型(date):日期类型的字段通常用于存储日期和时间,它们可以按照时间顺序进行排序。在Elasticsearch中,日期类型的字段可以使用多种格式进行存储,例如ISO-8601格式、UNIX时间戳等。如果要按照日期类型的字段进行排序,通常需要使用日期格式化字符串来指定日期格式。
需要注意的是,如果要按照非文本类型的字段进行排序,需要将字段的类型设置为相应的数据类型,否则可能会出现排序错误的情况。同时,如果要按照文本类型的字段进行排序,需要使用keyword类型的子字段或者使用fielddata特性来进行排序。
08. ElasticSearch 如何对文本类型的字段进行排序?
可以使用keyword类型的字段进行排序,查看索引的字段映射类型:
GET /my_index/_mapping
{"my_index" : {"mappings" : {"properties" : {"content" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"price" : {"type" : "long"},"title" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}}}
}
字段 title 和 content 都是keyword类型,因此可以排序:
GET /my_index/_search
{"query": {"match_all": {}},"sort": [{"title.keyword": {"order": "asc"}}]
}
{"took" : 3,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 4,"relation" : "eq"},"max_score" : null,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : null,"_source" : {"title" : "金都嘉怡假日酒店","content" : "北京","price" : 337},"sort" : ["金都嘉怡假日酒店"]},{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : null,"_source" : {"title" : "金都时尚情侣浪漫主题酒店","content" : "青岛","price" : 556},"sort" : ["金都时尚情侣浪漫主题酒店"]},{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : null,"_source" : {"title" : "金都欣欣24小时酒店","content" : "天津","price" : 200},"sort" : ["金都欣欣24小时酒店"]},{"_index" : "my_index","_type" : "_doc","_id" : "4","_score" : null,"_source" : {"title" : "金都自如酒店","content" : "上海","price" : 300},"sort" : ["金都自如酒店"]}]}
}
09. ElasticSearch 如何按照多个字段排序?
可以在 “sort” 参数中指定多个排序字段,可以指定每个字段的排序方式。
GET /my_index/_search
{"query": {"match_all": {}},"sort": [{"title.keyword": {"order": "asc"}},{"price": {"order": "desc"}}]
}
我们使用 sort 参数指定按照 title 字段进行升序排序,如果 title 字段相同,则按照 price 字段进行降序排序。
10. EalsticSearch 如何实现分页排序?
可以使用 “from” 和 “size” 参数来实现分页,可以使用 “sort” 参数来指定排序方式。
11. SpringBoot整合ES实现:按相关度排序
{"query": {"match": {"title": "金都酒店"}},"sort": [{"_score": {"order": "desc"}}]
}
@Slf4j
@Service
public class ElasticSearchImpl {@Autowiredprivate RestHighLevelClient restHighLevelClient;public void searchUser() throws IOException {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// query 查询MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");searchSourceBuilder.query(matchQueryBuilder);// 设置排序字段searchSourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.DESC));SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println(searchResponse);}
}
12. SpringBoot整合ES实现:按字段值排序
GET /my_index/_search
{"query": {"match_all": {}},"sort": [{"price": {"order": "asc"}}]
}
@Slf4j
@Service
public class ElasticSearchImpl {@Autowiredprivate RestHighLevelClient restHighLevelClient;public void searchUser() throws IOException {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// query 查询MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");searchSourceBuilder.query(matchQueryBuilder);// 设置排序字段searchSourceBuilder.sort(SortBuilders.fieldSort("price").order(SortOrder.ASC));SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println(searchResponse);}
}
13. SpringBoot整合ES实现:按文本类型字段排序
GET /my_index/_search
{"query": {"match_all": {}},"sort": [{"title.keyword": {"order": "asc"}}]
}
@Slf4j
@Service
public class ElasticSearchImpl {@Autowiredprivate RestHighLevelClient restHighLevelClient;public void searchUser() throws IOException {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// query 查询MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");searchSourceBuilder.query(matchQueryBuilder);// 设置排序字段searchSourceBuilder.sort(SortBuilders.fieldSort("title.keyword").order(SortOrder.ASC));SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println(searchResponse);}
}
我们使用SortBuilders.fieldSort方法来构建排序条件,其中name.keyword表示要排序的字段,.keyword表示要使用keyword类型的子字段进行排序,SortOrder.ASC表示升序排序。
14. SpringBoot整合ES实现:按多字段值排序
GET /my_index/_search
{"query": {"match_all": {}},"sort": [{"title.keyword": {"order": "asc"}},{"price": {"order": "desc"}}]
}
@Slf4j
@Service
public class ElasticSearchImpl {@Autowiredprivate RestHighLevelClient restHighLevelClient;public void searchUser() throws IOException {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// query 查询MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");searchSourceBuilder.query(matchQueryBuilder);// 设置排序字段searchSourceBuilder.sort(SortBuilders.fieldSort("title.keyword").order(SortOrder.ASC)).sort(SortBuilders.fieldSort("price").order(SortOrder.DESC));SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println(searchResponse);}
}