【问题标题】:Django Model and Many-to-Many Relationships -- finding most similar objectsDjango 模型和多对多关系——寻找最相似的对象
【发布时间】:2014-05-16 03:08:47
【问题描述】:

我遇到了一个无法解释的问题。

给定一个对象(在本例中为“文章”),我想使用另一种类型的对象(在本例中为“类别”)来确定哪些其他文章与文章 X 最相似,测量方式为它们共有的类别数量。文章和类别之间的关系是多对多的。用例是获取相关对象的快速列表以显示为链接。

我完全知道如何手写 SQL:

select 
    ac.article_id
from 
    Article_Category ac
where
    ac.category_id in 
    (
        select
            category_id
        from
            Article_Category
        where
            article_id = 1  -- get all categories for article in question
    )
    and ac.article_id <> 1
group by 
    ac.article_id
order by 
    count(ac.category_id) desc, random() limit 5

我正在苦苦挣扎的是如何使用 Django 模型聚合来匹配这个逻辑并且只运行一个查询。我会注意到的。如果可能的话,更喜欢在框架内进行。有人对此有意见吗?

【问题讨论】:

  • 如果raw queries不容易用django ORM语法表达,运行没有错。
  • 感谢您的快速回复。我当然可以运行原始查询,我只是想确保我不会错过使用 ORM 语法实现它的简单方法。我对使用它还很陌生。
  • 有些事情 django ORM 还没有涵盖(而且可能永远不会)。这就是他们提供原始查询的原因。
  • 既然你已经找到了答案——你可以answer your own question然后接受你的答案。这样,问题就结束了,其他人就会知道哪种解决方案有效。

标签: python django model


【解决方案1】:

现在我已经在模型框架中找到了一种方法来执行此操作。

related_article_list = Article.objects.filter(category=self.category.all())\
                       .exclude(id=self.id)
related_article_ids = related_article_list.values('id')\
                      .annotate(count=models.Count('id'))\
                      .order_by('-count','?')

在 related_article_list 部分中,匹配 2 个或更多类别的其他文章对象将分别包含在内。因此,当使用注释对它们进行计数时,数字将 > 1,并且可以按这种方式排序。

【讨论】:

    【解决方案2】:

    如果你真的想过滤所有类别的文章,我认为正确的答案应该是这样的:

    related_article_list = Article.objects.filter(category__in=self.category.all())\
                           .exclude(id=self.id)
    

    【讨论】:

      猜你喜欢
      • 2019-05-09
      • 2018-01-04
      • 2014-02-02
      • 2012-07-22
      • 2015-02-03
      • 2021-10-24
      • 1970-01-01
      • 2018-04-04
      • 2020-07-01
      相关资源
      最近更新 更多