【问题标题】:How do I get n items for each of the given list of foreignkey?如何为每个给定的外键列表获取 n 项?
【发布时间】:2018-07-31 22:10:48
【问题描述】:

我正在尝试找出一种在尽可能短的时间内执行此查询的方法。

number_of_results = 25
results = []
foreign_keys = [1,2,3,4,5]
for key in foreign_keys():
    results.append(Model.objects.filter(foreign_key=key)[:number_of_resutlts])

即使是单个查询集,也没关系。我想要完成的是减少数据库查询的数量。我的数据库是 PostgreSQL 10。

如何进一步简化这一点?

【问题讨论】:

  • .filter(foreign_key__in=[1,2,3,4,5]) 呢?
  • @gogaz 为每个键返回n结果吗?
  • __in 将为您提供所有具有 foreign_key 为 1,2,3,4,5 的模型对象
  • 它的分组依据和限制结果集。我认为没有一个步骤可以通过 Django 实现这一目标。
  • @NihalSharma 原始 sql 怎么样?

标签: python django django-queryset django-orm


【解决方案1】:

试试这个:

results.append(Model.objects.filter(foreign_key__in=key)[:number_of_resutlts])

【讨论】:

    【解决方案2】:

    这是一个group by and select n 问题。

    似乎没有单步操作可以通过 Django 实现这一点。但是,使用联合,我们可以通过单个查询来访问数据库以获取结果。联合内部有自己的成本 - 单独运行查询并选择不同的等。

    一种方法是使用原始 sql:

    objs = Model.objects.raw(
                    """SELECT rank_filter.* FROM (SELECT model.*, rank() 
                    OVER (PARTITION BY foreign_key_id ORDER BY created DESC) 
                    FROM model WHERE foreign_key_id IN (1,2,3,4,5)) 
                    rank_filter WHERE RANK <= n""") # replace n with 25
    
    for obj in objs:
        # do something
    

    【讨论】:

      【解决方案3】:

      从 Django 1.11 开始,您可以在这种情况下使用 QuerySet 的union 方法:

      qs = Model.objects.filter(foreign_key=foreign_keys[0])[:number_of_results]
      
      for fk in foreign_keys[1:]:
          qs = qs.union(Model.objects.filter(foreign_key=fk)[:number_of_results])
      

      https://docs.djangoproject.com/en/1.11/ref/models/querysets/#union

      【讨论】:

      • Union 会触发个别查询,不是吗?
      • 不,它会生成一个查询。
      • 是的,一个查询里面有多个联合。检查过了。
      猜你喜欢
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 2011-03-25
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2016-11-10
      相关资源
      最近更新 更多