【问题标题】:Improving efficiency of QuerySet filter by most recent record of a certain "type" (attribute)通过某种“类型”(属性)的最新记录提高 QuerySet 过滤器的效率
【发布时间】:2019-08-13 13:18:42
【问题描述】:

我会尽量保持简洁。我有以下查询:

organisation_survey_results = OrganisationSurveyResult.objects.filter(
    user=user
).order_by('survey', 'created_date')

这也会产生类似的结果:

organisation_survey_results = OrganisationSurveyResult.objects.filter(
    user=user
).order_by(
    'survey__id',
    '-created_date',
).distinct('survey__id',)

在上面,我根据用户匹配进行过滤。一切都很好。我已返回该用户的 5 条记录。

现在,如前所述,每条记录都带有以下attributesattribute“(链?)”:

唯一slug属性:

organisation_survey_result.organisation_survey.survey.slug

不可变(不变,创建时写入一次)created_date 属性:

organisation_survey_result.created_date

对于这五条记录,如果我遍历它们,我有:

django_1    | food
django_1    | 2019-08-12 15:45:49.384071+00:00
django_1    | drink
django_1    | 2019-08-12 15:45:49.390939+00:00
django_1    | politics
django_1    | 2019-08-12 15:45:49.397714+00:00
django_1    | money
django_1    | 2019-08-12 15:45:49.406612+00:00
django_1    | food
django_1    | 2019-08-13 11:26:55.831903+00:00

如您所见,我有两条记录,其中属性organisation_survey.survey.slugfood 出现了两次。 对于给定的用户,这很好。 记录可以而且将会在其他时间相互取代。


我的问题:

有没有办法可以在查询中过滤掉这些记录? (为了提高性能)...我希望能够在QuerySet 级别上执行此操作,以减少压力serialization 的数据。


版本:

`Django==2.2.1`
`djangorestframework==3.9.3`

数据库引擎:

`PostgreSQL`

【问题讨论】:

    标签: python django django-orm django-2.2


    【解决方案1】:

    所以,对我来说,虽然不在一个 QuerySet 中,但输出是一个应该是“可序列化”的 QuerySet:

    通过当前用户进行过滤,让我们的 QuerySet 领先一步:

    organisation_survey_results = OrganisationSurveyResult.objects.filter(user=user)
    

    为每个“organisation_survey”类型获取latest_records

    latest_records = organisation_survey_results.values(
        'user', 'organisation_survey'
    ).annotate(
        latest_created_date=Max('created_date')
    )
    

    回到最初的 QuerySet,通过 created_date 被“在”(created_date__in)过滤,latest_records 取自 latest_created_date 记录。

    organisation_survey_results = organisation_survey_results.filter(
        created_date__in=latest_records.values('latest_created_date')
    ).order_by(
        '-created_date'
    )
    

    给出了我在上述解决方案中所需要的确切描述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 2020-04-10
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 2018-10-08
      • 1970-01-01
      相关资源
      最近更新 更多