我有一个redis排序集,其中包含对象ID及其各自的排序分数。我需要检索这些对象的Django查询集,并根据排序集的分数进行排序。最有效的方法是什么?我的DB是postgresql。
目前,我正在分别检索redis排序集和未排序查询集。接下来,我根据python中排序集的分数对查询集进行排序。可以在这里有意义地切割步骤,例如以某种方式在检索点等排序查询集?
obj_ids_with_scr = get_ids_w_scr() #retrieves redis sorted set with scores
obj_ids = map(itemgetter(0),obj_ids_with_scr) # filters sorted set for just the obj ids
queryset = Widget.objects.filter(id__in=obj_ids) #unsorted queryset
a = dict(obj_ids_with_scr) #turning the sorted set into a dictionary
for obj_pk, sort_score in a:
obj = queryset.get(id=obj_pk) #get object with id equalling obj_pk
sort_score = obj #assign the object to the 'score' value of this key-value
result = a.values() #making a list of all values, that are now in sorted order
return result
答案 0 :(得分:1)
如果您使用的是postgres,则可以通过定义自己的here来模拟field
function in postgres所讨论的mysql的# config/initializers/delayed_job_config.rb
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 3
Delayed::Worker.max_run_time = 5.minutes
Delayed::Worker.read_ahead = 10
Delayed::Worker.default_queue_name = 'default'
Delayed::Worker.delay_jobs = !Rails.env.test?
Delayed::Worker.raise_signal_exceptions = :term
Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', 'delayed_job.log'))
语法:
order by field
然后用类似的东西打电话:
CREATE FUNCTION field(anyelement, VARIADIC anyarray) RETURNS numeric AS $$
SELECT
COALESCE(
( SELECT i FROM generate_subscripts($2, 1) gs(i)
WHERE $2[i] = $1 ),
0);
$$ LANGUAGE SQL STABLE
n.b。如果您这样选择,也可以优化您的python代码:
queryset = queryset.extra(
select={'manual': "FIELD(id, %s)" % (','.join(map(str, obj_ids)),) },
order_by=['manual']
)
批量返回widgets = Widgets.objects.in_bulk(obj_ids)
sorted_widgets = [ widgets[x] for x in obj_ids if x in widgets ]
映射dict
到id
个实例,这对您正在进行的排序类型很有用。您可以阅读更多相关信息here。