根据周次显示日期范围_Elasticsearch根据日期价格范围搜索酒店且排序
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根据日期价格范围搜索酒店且排序相关推荐
- oracle根据日期显示星期几,Oracle获取周几以及每周对应得开始日期和结束日期
Oracle获取周几以及每周对应得开始日期和结束日期 --获取近一年周的开始日期和结束日期,从星期日开始 select '2014'||sunday.the_week,decode(sign(sund ...
- 根据周次显示日期范围_Power BI动态技巧,利用DAX显示最近N天的数据
经常有星友问起,如何只显示最近X天的数据?这种做法很普遍,好消息是,在PowerBI中,实现起来还非常简单. 依然用PowerBI星球常用的案例模型,先来看一下显示最近7天的数据,下面是实现步骤. 动 ...
- python按照日期筛选数据_Pandas日期数据处理:如何按日期筛选、显示及统计数据...
前言 pandas有着强大的日期数据处理功能,本期我们来了解下pandas处理日期数据的一些基本功能,主要包括以下三个方面: 按日期筛选数据 按日期显示数据 按日期统计数据 运行环境为 windows ...
- linux修改显示日期格式,centos面板日期格式调整
centos面板日期格式调整 发布时间:2014-11-24 09:44:13来源:红联作者:halazi100 centos面板上日期和时间很容易弄混,用以下方法可以调整 # yum install ...
- vue+elementUI日期选择器实现选择日期,自动对应周几,并且是包含所选择日期的一周的日期
vue+elementUI日期选择器实现选择日期,自动对应周几 之前在公司的项目里面遇到这个问题,如今想起来在这里总结一下,如果有更好的方法,请各位大神多多指教. 在template里面给选择日期的e ...
- java 和 mysql 获取周 星期 的第一天 最后一天 或者 月的 日期(字符串转日期,日期转字符串,日期加减)...
获取周的第一天,最后一天 System.out.println(getStartEndDate("2016-05-01", 1)); 获取星期的第一天和最后一天 System.ou ...
- php 上次登陆时间,php使用cookie显示用户上次访问网站日期的方法
本文实例讲述了php使用cookie显示用户上次访问网站日期的方法.分享给大家供大家参考.具体实现方法如下:<?php if(!empty($_COOKIE['lastvisit'])){//先 ...
- elementui 利用周选择器 获取周一到周五的日期 和当前周
elementui 周选择器 获取周一到周五的日期 和当前是多少年多少周 <el-form-item><el-date-picker v-model="query.cycl ...
- java中获取当前一周日期和上周下周日期当前周数
1.获取当前日期所在周的所有日期 public static List<Date> dateToCurrentWeek(Date myDate) {Calendar cal = Cale ...
最新文章
- 为Visual Studio添加配色方案
- nag在逆向中是什么意思_OD 实验(四) - 去除 NAG 窗口的几种方法
- 短信宝 php使用,[php] 使用 短信宝 发送短信(thinkphp)
- 【Okio】Okio 简单入门
- openfeign远程调用不起作用解决_使用Spring Boot的spring.factories进行注入---SpringCloud Alibaba_若依微服务框架改造---工作笔记007
- Ubuntu Server Nginx 下配置 mono 下运行 asp.net mvc
- 说说年度补税退税的问题
- 面试:list集合去重
- cas 计算器 android,GeoGebra CAS计算器
- Elasticsearch 结合dynamic-synonym实现同义词热加载
- 勾股数规律(任意三个数能够满足勾股定理需要满足的条件)
- java web 表单提交_Java Web 表单(form)提交问题!
- 小波自适应阈值选取python_小波去噪阈值如何选取_小波阈值分析 - 全文
- 机器学习基础:模型评估(下)
- 不修条地铁,都不好意思叫自己大城市(附地铁发展图)
- 去除qq短视频水印 伪原创视频技巧
- 腾讯地图实现点击搜索地址功能
- 如何通过SEO搜索引擎关键词优化获客?
- 一大波年终工作总结PPT来袭赶紧收藏!
- 帝国CMS7.5仿《六皮游戏网》源码/手游门户网站模板/手机游戏下载模板
热门文章
- zookeeper学习笔记001-Address already in use: bind启动报错
- java 二叉树的各种遍历
- cocos2d-x之使用plist文件初试
- 素数c分解语言程序,PTA|《C语言程序设计实验与习题指导(第3版)》实验4-2-3 验证“哥德巴赫猜想” (20分)...
- 随想录(什么是软件架构师)
- 随想录(十年嵌入式总结)
- 多线程的那点儿事(之C++锁)
- html定义最小宽度,line-block的运用:最小宽度的设置
- 如何释放hdfs中的续租_装修中甲醛如何高效释放
- 计算机加工的过程和类型,3.1.2计算机信息加工的过程和类型