我有一个静态对象列表,大约500个项目。
此对象具有如下属性(id[int]、name[string]、attribute1
[string],属性2[string])。
我已将此对象序列化为字符串并作为
字符串键值。但我需要根据
不同的用户搜索过滤对象属性并给出
此列表发送给用户。
我可以用两种方法来实现,一种是将这个列表添加到表和索引中,然后使用sql应用搜索过滤器。另一个是我每次都从redis中提取这个列表并反序列化到
对象列表并使用linq应用筛选器。我在不同的服务器上有redis,db也是,我不想在每个web服务器上都有缓存的副本。
那么,为了取得最好的成绩,最好的方法是什么?或者有
另一种更快的方法?
最佳答案
与您列出的两种方法(在客户机中使用sql或反序列化和过滤)不同,我建议使用一种稍微不同的方法,它本质上是redis索引。
这个想法非常简单:假设对象的键名是obj1,obj2…objn,attribute1的值是val1,val2…valm,对于attribute1的每个值x,创建一个redis集,其键名类似于attribute1:valx:index
。集合的成员将是attribute1=valx的对象的键名。要做到这一点,请确保:
创建attribute1值为valx的objy时,将objy
添加到attribute1:valx:index
键。
将objy的attribute1从valx更新为valz时,从objy
中移除attribute1:valx:index
并将其添加到attribute1:valz:index
。
删除attribute1=valx的objy时,从objy
中删除attribute1:valx:index
。
或者,如果这对你的应用很重要的话,上面的操作应该是原子式的(即使用lua或watch/multi/exec块)。
这些点是维持指数所需要的。使用索引是通过获取attribute1:valx:index
集合的成员(例如smember)来完成的,该集合是在查找按attribute1=valx筛选的对象时设置的,然后通过它们的键名(例如objy
)来获取实际对象。或者,使用sort..get(例如SORT attribute1:valx:index GET obj*
)是另一种仅使用一个命令来实现此目的的方法。
对attribute2重复同样的步骤。还有几点:
考虑使用redis的散列来存储对象(例如hset objy attribute1 valx),以节省序列化开销和redis中值的更容易操作。
上面描述的简单索引可以做得更进一步-考虑使用集合操作,如sunion、sdiff和sinter,以获得更复杂的过滤选项。