在我的Ruby on Rails应用程序中,我正在为视图构建一个带有Fullcalendar JQuery插件的日历,并使用Icecube gem来计算事件递归。我也用Thinking Sphinx来搜索。
用户可以有多个日历,每个日历都有自己的一组循环事件。目前,这要求我必须加载所有用户日历和所有日历事件。然后我必须计算某个月内发生的所有事件。
我想缓存正在发生的事件的计算,并且认为我可以在events db列中序列化一个事件的数组。
那么我只需要加载用户日历,以及在这个月内发生的任何事件。
我不确定如何或即使我可以得到思考Sphinx搜索序列化数组虽然。这是可能的,我将如何在我的模型define_index块定义?
是否有一个更有效的方法,我可以缓存/搜索事件的发生时间?或者有没有其他的解决方案,人们已经用来解决类似的问题,搜索数组的时间对象?
您不需要任何花哨的东西,但您确实需要正确规划您的数据结构。
如果你坚持严格的一个事件一个记录方法,你可以更好地优化你的搜索。简单的方法是引入一个日历月列,它可以被索引,并在一个作用域中使用它来获取事件:
@events = @user.events.where(:yearmonth => yearmonth)
yearmonth
列包含YYYYMM
格式的值。如果需要,还可以按日期或星期索引。
一个循环事件会有很多子事件,通常一个事件是该事件类型的前一个实例的父级事件。您必须在足够长的时间内重复此操作,这可能会导致大量的记录,但是预计算它可能比为用户加载所有事件并试图找出给定日历月发生的事情更容易。
基于桌面或手机的日历应用程序可以将整个事件数据集保存在内存中,因为它通常一次只针对一个用户。在多用户系统或多用户*多租户系统中,除非您创建专门的持久服务器进程来执行该功能,否则您将有太多的数据来完成该功能。
让Sphinx能够搜索缓存事件的技巧是使用逗号分隔的时间戳列表。这允许您定义:multi类型的索引,如下所示:
define_index do
indexes :description
indexes :name, :sortable => true
indexes :location, :sortable => true
has :calendar_id
has :client_id
has :end_at
has :start_at
has "calendar_events.occurrence_cache", :as => :occurrence_cache, :type => :multi
set_property :delta => true
end
请注意,在定义多类型时使用表名是很重要的,否则我将得不到任何返回的结果。
现在我可以只使用sphinx作用域来查找在时间戳范围内发生的事件,而不必加载所有事件并确定它们的发生情况。
sphinx_scope(:ts_by_occurrence_at) do |occurrence_at_or_range|
{:with => {:occurrence_cache => occurrence_at_or_range}}
end