You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Lucene实现费率卡关联产品的日期与价格范围查询方案咨询

基于Lucene的可行方案

针对你的产品费率动态变动场景,结合订单日期筛选、价格范围过滤及价格排序需求,以下是几种基于Lucene的实现方案:

方案一:预计算常见订单周期的价格并索引

针对酒店类常见的短期订单场景,提前预计算产品在不同费率卡覆盖期内,对应不同订单时长(如1-30天)的日均价格或总价,将这些预计算值作为字段写入Lucene索引:

  • 索引阶段:对每个产品+费率卡组合,遍历费率卡有效期内的每一天,按星期附加费计算当日价格,再统计不同订单时长下的日均/总价,生成daily_avg_price_7d(7天日均价)、total_price_3d(3天总价)等字段。同时保留费率卡的startdate、enddate、priority字段用于日期匹配。
  • 查询阶段:先通过RangeQuery筛选出覆盖订单起止日期的费率卡,再根据订单时长匹配对应的预计算价格字段,过滤出价格在目标范围内的产品,最后按该预计算字段排序。
  • 注意:若订单周期超出预计算范围,需补充动态计算逻辑;同时要确保同一日期范围内取最高优先级费率卡的预计算价格。

方案二:用FunctionQuery动态计算订单周期价格

通过Lucene的自定义FunctionQuery,在查询时实时计算订单期间的实际价格,无需预计算,灵活性更高:

  • 索引阶段:将费率卡的所有字段(startdate、enddate、priority、基础price、各星期附加费)分别用对应类型的字段索引(日期用DatePointField,数值用DoublePointField)。
  • 查询阶段:
    1. 先用RangeQuery筛选出与订单起止日期有重叠的费率卡,再按priority排序取最高优先级的费率卡。
    2. 自定义ValueSource实现价格计算逻辑:遍历订单的每一天,根据星期几匹配对应的附加费,累加基础价得到当日价格,再计算整个订单周期的日均价或总价。
    3. 用FunctionQuery将计算结果作为价格范围筛选的依据,同时将该ValueSource作为排序字段,实现按实际价格排序。
  • 注意:动态计算会增加查询耗时,可优化点包括缓存日期与星期的映射关系、简化遍历逻辑等。

方案三:拆分费率卡为日粒度文档索引

将每个费率卡按有效期拆分为单天粒度的文档,每个文档对应产品某一天的实际价格:

  • 索引阶段:对每个费率卡的startdate到enddate的每一天,生成一个独立文档,包含product_id、date、actual_price(基础价+当日星期附加费)、priority字段。
  • 查询阶段:
    1. 用RangeQuery筛选出订单起止日期内的所有日粒度文档,按product_id分组,每组内取priority最高的文档集合。
    2. 计算每组文档的日均价格,过滤出日均价在目标范围内的产品,最后按日均价排序。
  • 优点:查询时计算逻辑简单;缺点是索引数据量会大幅增加(如年卡会生成365个文档),需根据业务规模权衡存储与性能。

方案四:用Lucene Join功能关联产品与费率卡

如果产品与费率卡是一对多关系,可采用父-子文档结构结合Join查询:

  • 索引阶段:产品作为父文档(存储产品基础信息),费率卡作为子文档(存储所有费率卡字段,通过product_id关联父文档)。
  • 查询阶段:
    1. 在子文档中筛选覆盖订单日期的费率卡,按priority排序取最高优先级的记录。
    2. 通过Lucene的Join查询关联到对应的父产品文档,计算该费率卡下订单周期的实际价格。
    3. 过滤价格符合范围的产品,按计算出的价格排序。
  • 优点:清晰区分产品与费率卡的关联关系,适合多费率卡的复杂场景;需注意优化Join查询的性能,如合理设置缓存。

通用注意事项

  • 优先级处理:无论采用哪种方案,都要确保同一日期范围内仅取最高优先级费率卡的价格进行计算,避免多费率卡冲突。
  • 价格逻辑对齐:明确业务需求是按订单总价还是日均价筛选排序,确保计算逻辑与业务规则一致。

内容的提问来源于stack exchange,提问作者user2799564

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:35:16