ES实现“小于XX时间”排前面(或后面)“大于XX时间”排后面(或前面)排序
比如有个字段是截止时间,如果过了截止时间,即逾期,否则未逾期。想对是否逾期排序,未逾期拍上面。这就是ES如何对不存在的逻辑字段排序问题。可以用 script 进行排序解决。
·
1、问题描述
一位学生问我一个问题,实现es查询:对于查询的结果要分成两类【过期和没过期,按照过期时间判断】。没过期的排在前面,过期的排在后面。最后,不管是过期的还是没过期的,在组内都再按照标定时间字段进行倒排序。
是否过期通过过期时间字段
进行判断。
2、误区
对于此类需求,要对一个不存在的字段
进行操作,第一应该想到的就是script_fields
一开始思路是这样的,伪代码如下:
GET <index>/_search
{
"script_fields": {
"是否逾期": {
"script": {
"lang": "painless",
"source": """
if(逾期=true) {
return 1;
}else{
return 0;
}
"""
}
}
},
"sort": [
{
"是否逾期": {
"order": "desc"
}
},
{
"标定时间":{
"order": "desc"
}
}
]
}
3、解决方案
上面方案后发现排序在外部无法对script_field
进行调用。于是对script
做出修改,把脚本查询写在sort
内部。基于product
索引模拟的案例如下:
这里假设product
索引中 价格> 3000 的类比上述案例中逾期,小于等于 3000 的类比上述案例中未逾期,然后按照价格(类比于标定日期)进行排序(product
索引数据在文末体现)
代码如下:
# 先根据价格级别(不存在字段)排序,大于3000的排上面,小于等于3000的排下面
# 其次按照价格倒叙排序
GET product/_search
{
"sort": [
{
"_script": {
"script": {
"lang": "painless",
"source": """
if(params['_source']['price']>3000) {
return 1;
}else{
return 0;
}
"""
},
"type": "number",
"order": "desc"
}
},
{
"price": {
"order": "desc"
}
}
]
}
4、附:Product
索引数据
```json
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"price" : 3999,
"lv":"qijianji",
"type":"phone",
"createtime":"2020-10-01T08:00:00Z",
"tags": [ "xingjiabi", "fashao","buka" ]
}
PUT /product/_doc/2
{
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"price" : 4999,
"lv":"qijianji",
"type":"phone",
"createtime":"2020-05-21T08:00:00Z",
"tags": [ "xingjiabi", "fashao","gongjiaoka" ]
}
PUT /product/_doc/3
{
"name" : "nfc phone",
"desc" : "shouji zhong de hongzhaji ",
"price" : 2999,
"lv":"gaoduanji",
"type":"phone",
"createtime":"2020-06-20",
"tags": [ "xingjiabi", "fashao", "menjinka" ]
}
PUT /product/_doc/4
{
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"price" : 999,
"lv":"baiyuanji",
"type":"erji",
"createtime":"2020-06-23",
"tags": [ "low", "bufangshui","yinzhicha" ]
}
PUT /product/_doc/5
{
"name" : "hongmi erji",
"desc" : "erji zhong de kendeji nfc",
"price" : 399,
"type":"erji",
"lv":"baiyuanji",
"createtime":"2020-07-20",
"tags": [ "lowbee","xuhangduan", "zhiliangx" ]
}
PUT /product/_doc/6
{
"name" : "xiaomi phone 10",
"desc" : "chongdian zeikuai diaodian gengkuai,chaoji wudi wangyuanjing,gaoshua dianjingping",
"price" : "5999",
"lv":"qijianji",
"type":"phone",
"createtime":"2020-07-27",
"tags": [ "120Hz", "120W", "120bianjiao" ]
}
PUT /product/_doc/7
{
"name" : "aipao SE2",
"desc" : "chule CPU,nothing",
"price" : "3299",
"lv":"qijianji",
"type":"phone",
"createtime":"2020-07-21",
"tags": [ "gejiucai", "gejiujiucai", "gexinjiucai" ]
}
PUT /product/_doc/8
{
"name" : "XS Max",
"desc" : "tingshuo yaochu 12 le zhongyu keyi huandiao shouli de 4S le",
"price" : 4399,
"lv":"qijianji",
"type":"shouji",
"createtime":"2020-08-19",
"tags": [ "5V1A", "4Gquanwangtong", "big" ]
}
PUT /product/_doc/9
{
"name" : "xiaomi TV",
"desc" : "Sydney's KTV",
"price" : 2998,
"lv":"gaoduanji",
"type":"erji",
"createtime":"2020-08-16",
"tags": [ "jumo", "jiatingyingyuan", "games" ]
}
PUT /product/_doc/10
{
"name" : "hongmi TV",
"desc" : "wo bishangmian nage genghuasuan,woye 2998,woye 70 cun,danshi wo genghaokan",
"price" : 2999,
"type":"TV",
"lv":"gaoduanji",
"createtime":"2020-08-28",
"tags": [ "dapian", "languang8K", "chaobo" ]
}
更多推荐
已为社区贡献18条内容
所有评论(0)