You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django联系人重复检测异常:重复项计数始终为1的问题排查

联系人重复项排查与修复

问题描述

我有一个大型联系人数据库,每个联系人归属特定用户,需要移除各用户联系人列表内的重复项。最初采用拼接user_id||name||address||zipcode等字段生成dupe_id,再通过annotate统计计数并筛选count>1的方式,多数情况有效,但部分明确的重复项计数始终为1。

测试代码

neighbors = neighbors.filter(name__icontains='JOHN WILLIAMS')

keyed_neighbors = neighbors.values('user_id', 'name', 'address', 'zipcode', 'pk'
    ).annotate(dupe_id=Concat(
        Cast('user_id', CharField(max_length=25)), Value('||'), 
        Upper('name'), Value('||'), 
        Upper('address'), Value('||'), 
        Substr('zipcode', 1, 5), Value('||'), 
        Upper('address_line_two'), output_field=CharField()))

dupes = keyed_neighbors.annotate(dupe_id_count=Count('dupe_id'))

返回结果子集

{'dupe_id': u'174563||JOHN WILLIAMS||222 WEDGEFIELD DR||28376||', 'dupe_id_count': 1}
    {'dupe_id': u'175875||JOHN WILLIAMS||4 TALLIN CT||29607||', 'dupe_id_count': 1}
    {'dupe_id': u'175875||JOHN WILLIAMS||4 TALLIN CT||29607||', 'dupe_id_count': 1}
    {'dupe_id': u'177178||JOHN WILLIAMS||5106 PAUL PEEL PL||28348||', 'dupe_id_count': 1}
    {'dupe_id': u'51||JOHN WILLIAMS||2410 COLGATE DR||28304||', 'dupe_id_count': 1}
    {'dupe_id': u'51||JOHN WILLIAMS||2410 COLGATE DR||28304||', 'dupe_id_count': 1}
    {'dupe_id': u'51||JOHN WILLIAMS||4 TALLIN CT||29607||', 'dupe_id_count': 1}

问题原因

问题出在values()方法里包含了pk字段。Django中,values()指定的字段会作为GROUP BY的分组依据,而pk是每个联系人的唯一标识,即使其他字段完全相同,只要pk不同,就会被分成不同的组,导致每个组的dupe_id_count始终为1。

修复方案

把pk从values()的参数列表中移除,这样分组就会基于user_id、name、address、zipcode这些用来生成dupe_id的字段,相同dupe_id的记录会被分到同一组,计数就能正确统计:

neighbors = neighbors.filter(name__icontains='JOHN WILLIAMS')

keyed_neighbors = neighbors.values('user_id', 'name', 'address', 'zipcode'
    ).annotate(dupe_id=Concat(
        Cast('user_id', CharField(max_length=25)), Value('||'), 
        Upper('name'), Value('||'), 
        Upper('address'), Value('||'), 
        Substr('zipcode', 1, 5), Value('||'), 
        Upper('address_line_two'), output_field=CharField()))

dupes = keyed_neighbors.annotate(dupe_id_count=Count('dupe_id')).filter(dupe_id_count__gt=1)

如果需要保留每个重复组的pk信息,可以在统计出重复的dupe_id后,再关联查询对应的记录。

内容的提问来源于stack exchange,提问作者Psyferre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:46:15