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


Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐