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 - 使用正则表达式查找多个匹配项并将它们打印出来[重复]