Elasticsearch的相关文章:

Elasticsearch读书笔记(一)

Docker版Elasticsearch的安装配置

基于SpringBoot、Elasticsearch酒店搜索

Elasticsearch根据日期价格范围搜索酒店

第四篇写了如何根据日期、价格范围来搜索酒店,用到了nested的相关知识点。在实际应用中,还有个排序的功能,例如:

整个需求变成了:

搜索符合关键词、日期范围、价格范围​的酒店列表,且按照其最低价格​排序。

前文中​搜索的DSL语句为:

{  "query": {    "bool": {      "must": [{          "match": {            "searchKeywords": "北京"          }        },        {          "nested": {            "path": "minPriceCalendar",            "query": {              "range": {                "minPriceCalendar.date": {                  "gte": "2020-11-11",                  "lte": "2020-11-15"                }              }            }          }        },        {          "nested": {            "path": "minPriceCalendar",            "query": {              "range": {                "minPriceCalendar.minPrice": {                  "gte": 450,                  "lte": 700                }              }            }          }        }      ]    }  }}

​结果中,只要符合上述条件的酒店都会搜索出来:

1、在北京。

2、11~15号有房。

3、价格在450~700。

按照道理只需要对搜出来的结果中的价格日历minPriceCalendar做一下指标聚合,再排序就行了​,如下:​

{  "query": {    "bool": {      "must": [        {          "match": {            "searchKeywords": "北京"          }        },        {          "nested": {            "path": "minPriceCalendar",            "query": {              "range": {                "minPriceCalendar.date": {                  "gte": "2020-11-14",                  "lte": "2020-11-15"                }              }            }          }        },        {          "nested": {            "path": "minPriceCalendar",            "query": {              "range": {                "minPriceCalendar.minPrice": {                  "gte": 200,                  "lte": 700                }              }            }          }        }      ]    }  },  "sort": [    {      "minPriceCalendar.minPrice": {        "mode": "min",        "order": "asc",        "nested": {          "path": "minPriceCalendar"        }      }    }  ]}

但是这里的问题就在于,Elasticsearch会把所有符合要求的文档原封不动地搜索出来。

看结果:

{  "took" : 1,  "timed_out" : false,  "_shards" : {    "total" : 1,    "successful" : 1,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : {      "value" : 3,      "relation" : "eq"    },    "max_score" : null,    "hits" : [      {        "_index" : "idx2",        "_type" : "_doc",        "_id" : "2",        "_score" : null,        "_source" : {          "hotelId" : 2,          "searchKeywords" : "北京 王府井",          "minPriceCalendar" : [            {              "date" : "2020-11-11",              "minPrice" : 110            },            {              "date" : "2020-11-12",              "minPrice" : 220            },            {              "date" : "2020-11-13",              "minPrice" : 330            },            {              "date" : "2020-11-14",              "minPrice" : 440            }          ]        },        "sort" : [          110        ]      },      {        "_index" : "idx2",        "_type" : "_doc",        "_id" : "5",        "_score" : null,        "_source" : {          "hotelId" : 5,          "searchKeywords" : "北京 金融街",          "minPriceCalendar" : [            {              "date" : "2020-11-11",              "minPrice" : 111            },            {              "date" : "2020-11-12",              "minPrice" : 222            },            {              "date" : "2020-11-13",              "minPrice" : 333            },            {              "date" : "2020-11-14",              "minPrice" : 444            }          ]        },        "sort" : [          111        ]      },      {        "_index" : "idx2",        "_type" : "_doc",        "_id" : "4",        "_score" : null,        "_source" : {          "hotelId" : 4,          "searchKeywords" : "北京 西单",          "minPriceCalendar" : [            {              "date" : "2020-11-15",              "minPrice" : 555            }          ]        },        "sort" : [          555        ]      }    ]  }}

注意看sort的值。

假设:

A酒店价格日历​:1号110,2号200,3号300​;

B酒店价格日历​:2号120,3号310​。

搜索日期2~3号,价格100~400的酒店,按最低价格排序。

AB酒店都命中,排序的时候,B酒店2~3号的最低价是120,大于A酒店的最低价200,排在前面。

但因为二者的价格日历都带出来了,所以A酒店最低价格是1号的110,B酒店最低价格是2号的​120,反而把A排在前面​。

所以我们还要对排序​再做一下过滤:

{  "query": {    "bool": {      "must": [        {          "match": {            "searchKeywords": "北京"          }        },        {          "nested": {            "path": "minPriceCalendar",            "query": {              "range": {                "minPriceCalendar.date": {                  "gte": "2020-11-14",                  "lte": "2020-11-15"                }              }            }          }        },        {          "nested": {            "path": "minPriceCalendar",            "query": {              "range": {                "minPriceCalendar.minPrice": {                  "gte": 200,                  "lte": 700                }              }            }          }        }      ]    }  },  "sort": [    {      "minPriceCalendar.minPrice": {        "mode": "min",        "order": "asc",        "nested": {          "path": "minPriceCalendar",          "filter": {            "bool": {              "must": [                {                  "range": {                    "minPriceCalendar.date": {                      "gte": "2020-11-14",                      "lte": "2020-11-15"                    }                  }                },                {                  "range": {                    "minPriceCalendar.minPrice": {                      "gte": 200,                      "lte": 700                    }                  }                }              ]            }          }        }      }    }  ]}

搜索结果如下:

{  "took" : 1,  "timed_out" : false,  "_shards" : {    "total" : 1,    "successful" : 1,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : {      "value" : 3,      "relation" : "eq"    },    "max_score" : null,    "hits" : [      {        "_index" : "idx2",        "_type" : "_doc",        "_id" : "2",        "_score" : null,        "_source" : {          "hotelId" : 2,          "searchKeywords" : "北京 王府井",          "minPriceCalendar" : [            {              "date" : "2020-11-11",              "minPrice" : 110            },            {              "date" : "2020-11-12",              "minPrice" : 220            },            {              "date" : "2020-11-13",              "minPrice" : 330            },            {              "date" : "2020-11-14",              "minPrice" : 440            }          ]        },        "sort" : [          440        ]      },      {        "_index" : "idx2",        "_type" : "_doc",        "_id" : "5",        "_score" : null,        "_source" : {          "hotelId" : 5,          "searchKeywords" : "北京 金融街",          "minPriceCalendar" : [            {              "date" : "2020-11-11",              "minPrice" : 111            },            {              "date" : "2020-11-12",              "minPrice" : 222            },            {              "date" : "2020-11-13",              "minPrice" : 333            },            {              "date" : "2020-11-14",              "minPrice" : 444            }          ]        },        "sort" : [          444        ]      },      {        "_index" : "idx2",        "_type" : "_doc",        "_id" : "4",        "_score" : null,        "_source" : {          "hotelId" : 4,          "searchKeywords" : "北京 西单",          "minPriceCalendar" : [            {              "date" : "2020-11-15",              "minPrice" : 555            }          ]        },        "sort" : [          555        ]      }    ]  }}

注意看sort的值,虽然minPriceCalendar还是把所有价格日历都带出来了,11、12、13号的结果,但是在排序的时候,把它们给过滤了。sort值对比前面的就符合要求了。

Java代码如下:

@GetMapping("/searchKeywordDatePrice")    @ResponseBody    public List searchKeywordDatePrice(@RequestParam() String searchKeywords,            @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate,            @RequestParam(required = false) Integer minPrice, @RequestParam(required = false) Integer maxPrice)            throws IOException {        if (Strings.isNullOrEmpty(startDate)) {            startDate = "2020-11-11";        }        if (Strings.isNullOrEmpty(endDate)) {            startDate = "2020-11-15";        }        if (Objects.isNull(minPrice)) {            minPrice = 0;        }        if (Objects.isNull(maxPrice)) {            maxPrice = Integer.MAX_VALUE;        }        SearchRequest searchRequest = new SearchRequest("idx2");        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();        // 关键词        boolQueryBuilder.must(QueryBuilders.matchQuery("searchKeywords", searchKeywords));        // 日期范围        boolQueryBuilder.must(QueryBuilders.nestedQuery("minPriceCalendar",                QueryBuilders.rangeQuery("minPriceCalendar.date").gte(startDate).lte(endDate), ScoreMode.None));        // 价格范围        boolQueryBuilder.must(QueryBuilders.nestedQuery("minPriceCalendar",                QueryBuilders.rangeQuery("minPriceCalendar.minPrice").gte(minPrice).lte(maxPrice), ScoreMode.None));        sourceBuilder.query(boolQueryBuilder);        // 分页        sourceBuilder.from(0);        sourceBuilder.size(10);        // 排序        BoolQueryBuilder nestedBoolQueryBuilder = QueryBuilders.boolQuery();        // 日期范围        nestedBoolQueryBuilder.must(QueryBuilders.rangeQuery("minPriceCalendar.date").gte(startDate).lte(endDate));        // 价格范围        nestedBoolQueryBuilder.must(QueryBuilders.rangeQuery("minPriceCalendar.minPrice").gte(minPrice).lte(maxPrice));        NestedSortBuilder nestedSortBuilder = new NestedSortBuilder("minPriceCalendar");        nestedSortBuilder.setFilter(nestedBoolQueryBuilder);        sourceBuilder.sort(new FieldSortBuilder("minPriceCalendar.minPrice").sortMode(SortMode.MIN).order(SortOrder.ASC)                .setNestedSort(nestedSortBuilder));        searchRequest.source(sourceBuilder);        SearchResponse res = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);        SearchHit[] searchHits = res.getHits().getHits();        Gson gson = new Gson();        List vos = Lists.newArrayList();        for (SearchHit hit : searchHits) {            String sourceAsString = hit.getSourceAsString();            HotelIdx2VO vo = gson.fromJson(sourceAsString, HotelIdx2VO.class);            vo.setMinPrice((int) hit.getSortValues()[0]);            vos.add(vo);        }        return vos;    }

与上一篇文章相比,添加了排序​的代码。

结果:

根据周次显示日期范围_Elasticsearch根据日期价格范围搜索酒店且排序相关推荐

  1. oracle根据日期显示星期几,Oracle获取周几以及每周对应得开始日期和结束日期

    Oracle获取周几以及每周对应得开始日期和结束日期 --获取近一年周的开始日期和结束日期,从星期日开始 select '2014'||sunday.the_week,decode(sign(sund ...

  2. 根据周次显示日期范围_Power BI动态技巧,利用DAX显示最近N天的数据

    经常有星友问起,如何只显示最近X天的数据?这种做法很普遍,好消息是,在PowerBI中,实现起来还非常简单. 依然用PowerBI星球常用的案例模型,先来看一下显示最近7天的数据,下面是实现步骤. 动 ...

  3. python按照日期筛选数据_Pandas日期数据处理:如何按日期筛选、显示及统计数据...

    前言 pandas有着强大的日期数据处理功能,本期我们来了解下pandas处理日期数据的一些基本功能,主要包括以下三个方面: 按日期筛选数据 按日期显示数据 按日期统计数据 运行环境为 windows ...

  4. linux修改显示日期格式,centos面板日期格式调整

    centos面板日期格式调整 发布时间:2014-11-24 09:44:13来源:红联作者:halazi100 centos面板上日期和时间很容易弄混,用以下方法可以调整 # yum install ...

  5. vue+elementUI日期选择器实现选择日期,自动对应周几,并且是包含所选择日期的一周的日期

    vue+elementUI日期选择器实现选择日期,自动对应周几 之前在公司的项目里面遇到这个问题,如今想起来在这里总结一下,如果有更好的方法,请各位大神多多指教. 在template里面给选择日期的e ...

  6. java 和 mysql 获取周 星期 的第一天 最后一天 或者 月的 日期(字符串转日期,日期转字符串,日期加减)...

    获取周的第一天,最后一天 System.out.println(getStartEndDate("2016-05-01", 1)); 获取星期的第一天和最后一天 System.ou ...

  7. php 上次登陆时间,php使用cookie显示用户上次访问网站日期的方法

    本文实例讲述了php使用cookie显示用户上次访问网站日期的方法.分享给大家供大家参考.具体实现方法如下:<?php if(!empty($_COOKIE['lastvisit'])){//先 ...

  8. elementui 利用周选择器 获取周一到周五的日期 和当前周

    elementui 周选择器 获取周一到周五的日期 和当前是多少年多少周 <el-form-item><el-date-picker v-model="query.cycl ...

  9. java中获取当前一周日期和上周下周日期当前周数

    1.获取当前日期所在周的所有日期  public static List<Date> dateToCurrentWeek(Date myDate) {Calendar cal = Cale ...

最新文章

  1. 为Visual Studio添加配色方案
  2. nag在逆向中是什么意思_OD 实验(四) - 去除 NAG 窗口的几种方法
  3. 短信宝 php使用,[php] 使用 短信宝 发送短信(thinkphp)
  4. 【Okio】Okio 简单入门
  5. openfeign远程调用不起作用解决_使用Spring Boot的spring.factories进行注入---SpringCloud Alibaba_若依微服务框架改造---工作笔记007
  6. Ubuntu Server Nginx 下配置 mono 下运行 asp.net mvc
  7. 说说年度补税退税的问题
  8. 面试:list集合去重
  9. cas 计算器 android,GeoGebra CAS计算器
  10. Elasticsearch 结合dynamic-synonym实现同义词热加载
  11. 勾股数规律(任意三个数能够满足勾股定理需要满足的条件)
  12. java web 表单提交_Java Web 表单(form)提交问题!
  13. 小波自适应阈值选取python_小波去噪阈值如何选取_小波阈值分析 - 全文
  14. 机器学习基础:模型评估(下)
  15. 不修条地铁,都不好意思叫自己大城市(附地铁发展图)
  16. 去除qq短视频水印 伪原创视频技巧
  17. 腾讯地图实现点击搜索地址功能
  18. 如何通过SEO搜索引擎关键词优化获客?
  19. 一大波年终工作总结PPT来袭赶紧收藏!
  20. 帝国CMS7.5仿《六皮游戏网》源码/手游门户网站模板/手机游戏下载模板

热门文章

  1. zookeeper学习笔记001-Address already in use: bind启动报错
  2. java 二叉树的各种遍历
  3. cocos2d-x之使用plist文件初试
  4. 素数c分解语言程序,PTA|《C语言程序设计实验与习题指导(第3版)》实验4-2-3 验证“哥德巴赫猜想” (20分)...
  5. 随想录(什么是软件架构师)
  6. 随想录(十年嵌入式总结)
  7. 多线程的那点儿事(之C++锁)
  8. html定义最小宽度,line-block的运用:最小宽度的设置
  9. 如何释放hdfs中的续租_装修中甲醛如何高效释放
  10. 计算机加工的过程和类型,3.1.2计算机信息加工的过程和类型