00. 數(shù)據(jù)準(zhǔn)備
PUT /my_index/_doc/1
{
"title": "金都時(shí)尚情侶浪漫主題酒店",
"content": "青島",
"price": 556
}
PUT /my_index/_doc/2
{
"title": "金都嘉怡假日酒店",
"content": "北京",
"price": 337
}
PUT /my_index/_doc/3
{
"title": "金都欣欣24小時(shí)酒店",
"content": "天津",
"price": 200
}
PUT /my_index/_doc/4
{
"title": "金都自如酒店",
"content": "上海",
"price": 300
}
01. Elasticsearch 默認(rèn)的排序方式是什么?
ElasticSearch 默認(rèn)的排序方式是相關(guān)性排序。相關(guān)性排序是根據(jù)查詢條件與文檔的匹配程度來(lái)計(jì)算每個(gè)文檔的相關(guān)性得分,然后按照得分從高到低進(jìn)行排序。相關(guān)性排序是 ElasticSearch 中最常用的排序方式,因?yàn)樗梢愿鶕?jù)查詢條件與文檔的匹配程度來(lái)確定文檔的排序位置,從而提高查詢結(jié)果的準(zhǔn)確性。
在相關(guān)性排序中,ElasticSearch 使用一種稱為 TF-IDF 的算法來(lái)計(jì)算每個(gè)查詢條件與文檔的匹配程度。TF-IDF 算法可以有效地確定查詢條件與文檔的匹配程度,從而計(jì)算出每個(gè)文檔的相關(guān)性得分。具體來(lái)說(shuō),TF-IDF 算法會(huì)根據(jù)查詢條件中每個(gè)詞的詞頻(TF)和文檔集合中包含該詞的文檔數(shù)的倒數(shù)(IDF)來(lái)計(jì)算每個(gè)查詢條件與文檔的匹配程度,然后將所有查詢條件的匹配程度加權(quán)求和,得到文檔的相關(guān)性得分。
需要注意的是,相關(guān)性排序并不一定是最優(yōu)的排序方式,因?yàn)樗豢紤]了查詢條件與文檔的匹配程度,而沒有考慮其他因素,例如文檔的時(shí)間戳、文檔的重要性等。在某些情況下,其他排序方式可能更適合。在這種情況下,可以通過在查詢語(yǔ)句中指定排序方式來(lái)實(shí)現(xiàn)其他排序方式。
在 Elasticsearch 中, 相關(guān)性得分由一個(gè)浮點(diǎn)數(shù)進(jìn)行表示,并在搜索結(jié)果中通過 _score
參數(shù)返回, 默認(rèn)排序是 _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小時(shí)酒店",
"content" : "天津",
"price" : 200
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.36585158,
"_source" : {
"title" : "金都時(shí)尚情侶浪漫主題酒店",
"content" : "青島",
"price" : 556
}
}
]
}
}
02. Elasticsearch 支持哪些排序方式?
Elasticsearch 支持多種排序方式,包括按照相關(guān)度得分排序、按照字段值排序、按照多個(gè)字段排序等。
03. ElasticSearch 如何指定排序方式?
可以在查詢語(yǔ)句中使用 “sort” 參數(shù)來(lái)指定排序方式,可以指定排序字段、排序方式等。
04. ElasticSearch 如何按照相關(guān)性排序?
默認(rèn)情況下,Elasticsearch 會(huì)根據(jù)文檔與查詢的相關(guān)度得分進(jìn)行排序,得分越高的文檔排在越前面。
{
"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小時(shí)酒店",
"content" : "天津",
"price" : 200
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.36585158,
"_source" : {
"title" : "金都時(shí)尚情侶浪漫主題酒店",
"content" : "青島",
"price" : 556
}
}
]
}
}
05. ElasticSearch 查詢結(jié)果如何不按照相關(guān)性排序?
Elasticsearch的過濾器(Filter)不會(huì)計(jì)算相關(guān)性得分,它們只是根據(jù)指定的條件來(lái)過濾文檔,而不會(huì)影響文檔的相關(guān)性得分。相比之下,查詢(Query)會(huì)計(jì)算相關(guān)性得分,它們會(huì)根據(jù)查詢條件來(lái)計(jì)算文檔的相關(guān)性得分,并將得分作為文檔的排序依據(jù)。因此,如果您需要根據(jù)相關(guān)性對(duì)文檔進(jìn)行排序,應(yīng)該使用查詢(Query)而不是過濾器(Filter)。
Elasticsearch的過濾器(Filter)可以用來(lái)過濾文檔,以便于在查詢時(shí)只返回符合條件的文檔。以下是使用過濾器的一些常見方法:
使用布爾過濾器(Boolean Filter):布爾過濾器可以將多個(gè)過濾器組合起來(lái),以實(shí)現(xiàn)復(fù)雜的過濾邏輯。例如,可以使用must、should、must_not等關(guān)鍵字來(lái)組合多個(gè)過濾器。
使用范圍過濾器(Range Filter):范圍過濾器可以根據(jù)指定的范圍來(lái)過濾文檔。例如,可以使用range關(guān)鍵字來(lái)指定字段的范圍。
使用存在過濾器(Exists Filter):存在過濾器可以過濾出指定字段存在或不存在的文檔。例如,可以使用exists關(guān)鍵字來(lái)指定字段是否存在。
使用緩存過濾器(Cache Filter):緩存過濾器可以將過濾結(jié)果緩存起來(lái),以提高查詢性能。例如,可以使用cache關(guān)鍵字來(lái)指定是否緩存過濾結(jié)果。
GET /my_index/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"price": "300"
}
}
]
}
}
}
06. ElasticSearch 如何按照字段的值排序?
Elasticsearch可以按照字段的值進(jìn)行排序,可以使用sort參數(shù)來(lái)指定排序方式。
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小時(shí)酒店",
"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" : "金都時(shí)尚情侶浪漫主題酒店",
"content" : "青島",
"price" : 556
},
"sort" : [
556
]
}
]
}
}
07. ElasticSearch 排序字段的類型?
在Elasticsearch中,排序字段的類型非常重要,因?yàn)椴煌愋偷淖侄慰赡軙?huì)導(dǎo)致排序結(jié)果不同。以下是一些常見的排序字段類型及其特點(diǎn):
文本類型(text):文本類型的字段通常用于全文搜索,它們會(huì)被分詞器處理成多個(gè)詞條,因此在排序時(shí)可能會(huì)出現(xiàn)意外的結(jié)果。如果要按照文本類型的字段進(jìn)行排序,通常需要使用keyword類型的子字段,或者使用fielddata特性來(lái)將文本類型的字段轉(zhuǎn)換為可排序的類型(ES新版本不支持了)。
數(shù)字類型(numeric):數(shù)字類型的字段通常用于存儲(chǔ)數(shù)字,它們可以按照數(shù)值大小進(jìn)行排序。在Elasticsearch中,數(shù)字類型的字段包括整數(shù)類型(integer、long、short、byte)和浮點(diǎn)數(shù)類型(float、double)。如果要按照數(shù)字類型的字段進(jìn)行排序,通常不需要進(jìn)行額外的配置。
日期類型(date):日期類型的字段通常用于存儲(chǔ)日期和時(shí)間,它們可以按照時(shí)間順序進(jìn)行排序。在Elasticsearch中,日期類型的字段可以使用多種格式進(jìn)行存儲(chǔ),例如ISO-8601格式、UNIX時(shí)間戳等。如果要按照日期類型的字段進(jìn)行排序,通常需要使用日期格式化字符串來(lái)指定日期格式。
需要注意的是,如果要按照非文本類型的字段進(jìn)行排序,需要將字段的類型設(shè)置為相應(yīng)的數(shù)據(jù)類型,否則可能會(huì)出現(xiàn)排序錯(cuò)誤的情況。同時(shí),如果要按照文本類型的字段進(jìn)行排序,需要使用keyword類型的子字段或者使用fielddata特性來(lái)進(jìn)行排序。
08. ElasticSearch 如何對(duì)文本類型的字段進(jìn)行排序?
可以使用keyword類型的字段進(jìn)行排序,查看索引的字段映射類型:
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" : "金都時(shí)尚情侶浪漫主題酒店",
"content" : "青島",
"price" : 556
},
"sort" : [
"金都時(shí)尚情侶浪漫主題酒店"
]
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : null,
"_source" : {
"title" : "金都欣欣24小時(shí)酒店",
"content" : "天津",
"price" : 200
},
"sort" : [
"金都欣欣24小時(shí)酒店"
]
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "4",
"_score" : null,
"_source" : {
"title" : "金都自如酒店",
"content" : "上海",
"price" : 300
},
"sort" : [
"金都自如酒店"
]
}
]
}
}
09. ElasticSearch 如何按照多個(gè)字段排序?
可以在 “sort” 參數(shù)中指定多個(gè)排序字段,可以指定每個(gè)字段的排序方式。
GET /my_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"title.keyword": {
"order": "asc"
}
},
{
"price": {
"order": "desc"
}
}
]
}
我們使用 sort 參數(shù)指定按照 title 字段進(jìn)行升序排序,如果 title 字段相同,則按照 price 字段進(jìn)行降序排序。
10. EalsticSearch 如何實(shí)現(xiàn)分頁(yè)排序?
可以使用 “from” 和 “size” 參數(shù)來(lái)實(shí)現(xiàn)分頁(yè),可以使用 “sort” 參數(shù)來(lái)指定排序方式。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-781337.html
11. SpringBoot整合ES實(shí)現(xiàn):按相關(guān)度排序
{
"query": {
"match": {
"title": "金都酒店"
}
},
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
@Slf4j
@Service
public class ElasticSearchImpl {
@Autowired
private RestHighLevelClient restHighLevelClient;
public void searchUser() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// query 查詢
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");
searchSourceBuilder.query(matchQueryBuilder);
// 設(shè)置排序字段
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實(shí)現(xiàn):按字段值排序
GET /my_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {
"order": "asc"
}
}
]
}
@Slf4j
@Service
public class ElasticSearchImpl {
@Autowired
private RestHighLevelClient restHighLevelClient;
public void searchUser() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// query 查詢
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");
searchSourceBuilder.query(matchQueryBuilder);
// 設(shè)置排序字段
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實(shí)現(xiàn):按文本類型字段排序
GET /my_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"title.keyword": {
"order": "asc"
}
}
]
}
@Slf4j
@Service
public class ElasticSearchImpl {
@Autowired
private RestHighLevelClient restHighLevelClient;
public void searchUser() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// query 查詢
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");
searchSourceBuilder.query(matchQueryBuilder);
// 設(shè)置排序字段
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方法來(lái)構(gòu)建排序條件,其中name.keyword表示要排序的字段,.keyword表示要使用keyword類型的子字段進(jìn)行排序,SortOrder.ASC表示升序排序。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-781337.html
14. SpringBoot整合ES實(shí)現(xiàn):按多字段值排序
GET /my_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"title.keyword": {
"order": "asc"
}
},
{
"price": {
"order": "desc"
}
}
]
}
@Slf4j
@Service
public class ElasticSearchImpl {
@Autowired
private RestHighLevelClient restHighLevelClient;
public void searchUser() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// query 查詢
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","金都酒店");
searchSourceBuilder.query(matchQueryBuilder);
// 設(shè)置排序字段
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);
}
}
到了這里,關(guān)于ElasticSearch系列 - SpringBoot整合ES:實(shí)現(xiàn)搜索結(jié)果排序 sort的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!