Django 使用查询集和正则表达式查找重复项

Posted

技术标签:

【中文标题】Django 使用查询集和正则表达式查找重复项【英文标题】:Django find duplicates with queryset and regex 【发布时间】:2015-03-20 18:13:07 【问题描述】:

在 Django 中,是否可以使用查询集和正则表达式查找重复项?

Django select only rows with duplicate field values 显示不使用正则表达式:

self.values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

我有一个模型:

class company(models.Model):
   Website = models.URLField(blank=True, null=True )

我想用正则表达式查找重复项

例如。

Company.objects.create(Website='http://example.com')
Company.objects.create(Website='http://www.example.com')

这两个是同一个网站。我想使用正则表达式,以便它将这些公司作为重复返回。

我知道有这样的过滤器使用正则表达式。我不确定如何更新它以使用正则表达式:

self.values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

我想做这样的事情:

Website__iregex='http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'

更新 有一些混乱,所以我举个例子。

这是我的数据库的样子

Company.objects.create(Website='http://example.com')
Company.objects.create(Website='http://www.example.com')
Company.objects.create(Website='http://example.org', Name='a')
Company.objects.create(Website='http://example.org', Name='b')

当我打电话时

Company.objects.all().values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

返回:

    http://example.org(来自 name=a)和http://example.org(来自 name=b)

这缺少 example.com 和 www.example.com 是同一个网站。

我想使用正则表达式,以便告诉 django example.com 和 www.example.com 是同一个网站。

我要修改:

Company.objects.all().values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

以便它返回重复项:

    http://example.org(来自 name=a)和http://example.org(来自 name=b)

    example.com www.example.com

【问题讨论】:

.annotate(count=Count('id')).order_by().filter(count__gt=1) 是否有效??? 【参考方案1】:

使用__icontains:

Company.objects.filter(Website__icontains='example.com')

这将产生:

`ILIKE %'example.com'%. 

如果存在于 Company 表中,它将因此返回以下记录:

 http://example.com, http://www.example.com

【讨论】:

我正在寻找一种方法来查找重复项。在我的示例中,我想要一种方法来查找 Django 将实现“example.com”和“www.example.com”是同一个网站的重复项。 和上面的查询集它会 我想运行一个查询集来查找重复的网站。您的代码假设我知道重复的网址。它还创建了一个我认为是错字的对象。我想修改这个表达式,让它意识到 www 和非 www 是同一个网站: values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1) 更新了我的答案。而且我在那里复制有点快,没有看到你的第一个查询集是创建的。 我想要什么有些困惑。我更新了帖子。【参考方案2】:

我在某些项目中有类似的数据库结构——我存储了一些实体的 url。为了查找重复项,我还存储了 url 的“域”。

因此,关于您的示例,数据库结构将是:

id |           url          | domain
-----------------------------------------
1  | http://www.example.com | example.com
2  | http://example.com     | example.com

然后很容易找到重复项或找到与特定域相关的 url/实体。

您可能会认为使用这种方法来检测重复项是多余的。

但是你的方法有两个很大的缺点:

1) 编写正确的正则表达式来匹配域变化是不可能的

匹配“www.example.com”和“example.com”很容易。 “example.co.uk”和“www.example.co.uk”或者“www.старт.рф”和“старт.рф”怎么样?这些都是有效的域名。

2) 从长远来看,你是在打你的腿 - 在不断增长的数据库表上编写复杂的正则表达式影响你的表现。

附言- 我使用“tldextract”库来获取 url 的域。

【讨论】:

以上是关于Django 使用查询集和正则表达式查找重复项的主要内容,如果未能解决你的问题,请参考以下文章

Python - 使用正则表达式查找多个匹配项并将它们打印出来[重复]

python)使用正则表达式查找所有匹配项(从 re.search 更改为 re.findall)[重复]

如何在 MySQL 选择查询中编写正则表达式?

脚本应用

从 pandas 数据框列中查找所有正则表达式匹配项

使用正则表达式查找两个字符串之间的多个匹配项