如何将关联多表事件数据正确索引到Solr以支持按星期、时段查询
Solr 多表整合索引实现方案
核心思路
以event_id为唯一维度聚合两张表的数据,单event对应一条Solr文档,slot表的多时段配置通过Solr多值字段存储,天然支持多条件过滤查询。
1. Solr 字段Schema设计
需要在solr的managed-schema配置文件中将event_id设为唯一主键,避免重复索引,核心字段定义如下:
event_id:string类型,作为全局唯一主键,对应event_listing表的event_idfrom_date:pdate类型,存储事件生效开始日期,支持日期范围过滤to_date:pdate类型,存储事件生效结束日期,支持日期范围过滤dayOfWeek:多值int类型,存储该事件所有配置的星期几取值(1~7对应周一到周日,按需调整)slot_start_seconds:多值int类型,存储每个时段的开始时间换算为当天0点后的秒数,方便范围查询slot_end_seconds:多值int类型,存储每个时段的结束时间换算为当天0点后的秒数
如果不需要太精细的查询性能,也可以直接存储slot_start_time、slot_end_time为多值string类型,格式统一为HH:mm:ss即可。
2. 数据整合索引流程
方式1:使用Solr DataImportHandler(DIH)直接拉取整合
无需额外写代码,直接配置DIH的data-config.xml即可自动完成多表关联聚合,示例配置:
<dataConfig> <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://数据库地址:3306/库名" user="用户名" password="密码" /> <document> <entity name="event" query="select event_id, from_date, to_date from event_listing"> <field column="event_id" name="event_id" /> <field column="from_date" name="from_date" /> <field column="to_date" name="to_date" /> <!-- 关联子实体拉取当前event的所有slot配置 --> <entity name="slot" query="select dayOfWeek, TIME_TO_SEC(slot_start_time) as slot_start_seconds, TIME_TO_SEC(slot_end_time) as slot_end_seconds from slot_data where event_id = '${event.event_id}'"> <field column="dayOfWeek" name="dayOfWeek" /> <field column="slot_start_seconds" name="slot_start_seconds" /> <field column="slot_end_seconds" name="slot_end_seconds" /> </entity> </entity> </document> </dataConfig>
DIH会自动将同个event下的多个slot字段值合并为多值数组,存储到单条Solr文档中,完全满足单event一条索引的要求。
方式2:代码侧聚合后提交索引
如果需要做复杂的预处理逻辑,可以自己写导入脚本:
- 批量拉取event_listing全量数据
- 按event_id批量关联查询slot_data的所有时段配置
- 把同一个event的所有slot的
dayOfWeek、slot_start_seconds、slot_end_seconds分别合并为数组,组装成单条Solr文档后批量提交
3. 查询实现示例
比如要查询「2024年全年、周六(dayOfWeek=6)14:00~16:00可用的事件」,查询语句如下:
q=*:* &fq=from_date:[2024-01-01T00:00:00Z TO *] &fq=to_date:[* TO 2024-12-31T23:59:59Z] &fq=dayOfWeek:6 &fq=slot_start_seconds:[* TO 50400] &fq=slot_end_seconds:[57600 TO *]
其中14:00换算为秒数是14*3600=50400,16:00换算为秒数是16*3600=57600。
可选优化
如果业务仅需要精确匹配某星期几的特定时段,可以把dayOfWeek+时段拼接为多值字符串,格式为{dayOfWeek}#{HH:mm:ss}#{HH:mm:ss},查询时直接做精确匹配即可,逻辑更简单。
内容的提问来源于stack exchange,提问作者Anshul Verma
相关产品推荐
相关产品推荐

