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" ] }