基于Elasticsearch与Searchkick实现用户近7天浏览事件的索引方案咨询
解决Elasticsearch + Searchkick下的近7天事件浏览筛选问题
针对你的需求,这里提供两种可行的索引设计方案,分别适配不同的业务场景:
方案1:在Event索引中存储带时间戳的嵌套点击记录
将用户点击记录从单纯的ID数组改为嵌套对象数组,每个对象包含user_id和clicked_at字段,同时保留用户维度与时间维度的信息。
配置Event模型的Searchkick索引
class Event < ApplicationRecord searchkick mappings: { properties: { user_clicks: { type: "nested", properties: { user_id: { type: "integer" }, clicked_at: { type: "date" } } } # 这里添加事件的其他基础字段,比如title、start_time等 } } def search_data { # 映射事件基础字段 title: title, start_time: start_time, # 映射嵌套点击记录 user_clicks: user_clicks } end end
用户点击时更新记录
用户点击事件时,维护user_clicks数组:若该用户已有点击记录则更新时间,否则新增记录,之后触发索引重建:
def track_user_click(user) existing_click = user_clicks.find { |c| c[:user_id] == user.id } if existing_click existing_click[:clicked_at] = Time.current else user_clicks << { user_id: user.id, clicked_at: Time.current } end save reindex end
实现“近7天浏览”筛选
通过嵌套查询过滤当前用户近7天内点击过的事件:
seven_days_ago = 7.days.ago Event.search( "*", where: { user_clicks: { nested: { path: "user_clicks", query: { bool: { must: [ { term: { "user_clicks.user_id": current_user.id } }, { range: { "user_clicks.clicked_at": { gte: seven_days_ago } } } ] } } } } } )
方案2:单独创建用户点击记录索引(推荐高点击量场景)
如果事件的点击量较大,嵌套数组会导致Event文档体积持续膨胀,影响索引性能。此时建议单独创建UserEventClick模型,专门存储用户点击事件的时间与关联关系。
创建UserEventClick模型并配置Searchkick
class UserEventClick < ApplicationRecord belongs_to :user belongs_to :event searchkick end
用户点击时创建记录
用户点击事件时,直接新增一条点击记录:
def track_user_click(user) UserEventClick.create!(user: user, event: self, created_at: Time.current) end
查询用户近7天点击的事件
先通过点击记录索引获取事件ID列表,再过滤事件索引:
seven_days_ago = 7.days.ago # 获取近7天点击的事件ID clicked_event_ids = UserEventClick.search( "*", where: { user_id: current_user.id, created_at: { gte: seven_days_ago } }, fields: [:event_id], limit: nil ).map(&:event_id) # 查询对应的事件列表 Event.search( "*", where: { id: clicked_event_ids } )
方案对比
- 嵌套对象方案:适合点击量较小的场景,仅需一次查询即可获取结果,逻辑简单,但Event文档会随点击量增长。
- 单独索引方案:适合高点击量场景,Event索引体积稳定,维护更灵活,但需要额外的模型和两次查询(或用Elasticsearch的terms lookup优化为单次查询)。
内容的提问来源于stack exchange,提问作者Remember_me
相关产品推荐
相关产品推荐

