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

开发Rails Job合并含相似电话号码的重复用户记录技术问询

问题解答

你的核心方向是对的——通过号码最后10位匹配同用户的重复记录,符合不同国家码的号码特征,也能覆盖你提到的场景。但当前代码存在几个关键问题,导致无法正确获取匹配项,以下是具体修正方案和合并逻辑:

一、修正查询逻辑

当前代码里的user[user.length * -1..-1]完全错误,你要操作的是用户的phone字段而非user对象本身。另外,号码里的非数字字符(比如-)会干扰匹配,必须先清洗提取纯数字,再取最后10位做匹配。

修正后的Job代码:

class MergeRecordsJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    # 通过ID取用户,避免直接传对象引发序列化问题
    user = User.find(user_id)
    # 清洗电话号码,提取纯数字
    cleaned_phone = user.phone.gsub(/\D/, '')
    # 取纯数字的最后10位作为匹配键
    last_10_digits = cleaned_phone[-10..-1]

    # 查询所有纯数字结尾为这10位的用户,排除当前用户自身
    matches = User.where("regexp_replace(phone, '\\D', '', 'g') LIKE ?", "%#{last_10_digits}")
                  .where.not(id: user.id)

    p "找到#{matches.count}条重复记录"

    # 执行合并逻辑
    merge_duplicates(user, matches) unless matches.empty?
  end

  private

  def merge_duplicates(primary_user, duplicates)
    # 开启事务,确保合并操作的原子性,避免数据不一致
    ActiveRecord::Base.transaction do
      # 1. 迁移关联数据(按需调整):将重复记录的关联资源(如订单、评论)转移到主记录
      duplicates.each do |dup|
        # 示例:若存在orders关联,将dup的订单归属更新为主记录ID
        # dup.orders.update_all(user_id: primary_user.id)
        # 其他关联模型同理处理
      end

      # 2. 确保主记录保留带国家码的号码:如果主记录无国家码,从重复记录中选取带国家码的替换
      primary_cleaned = primary_user.phone.gsub(/\D/, '')
      best_phone = duplicates.map { |d| d.phone }.select { |p| p.gsub(/\D/, '').length > 10 }.first || primary_user.phone
      primary_user.update!(phone: best_phone)

      # 3. 删除重复记录
      duplicates.destroy_all
    end
  end
end

二、优化与建议

  • 批量分组处理:直接单条调用Job处理1000条样本会重复查询同一组记录,建议先按清洗后的最后10位分组,批量发起Job,同时给User表添加merged_at字段标记已处理记录,避免重复执行。
  • 添加函数索引:为避免全表扫描,提升查询速度,给phone字段创建函数索引:
    CREATE INDEX idx_users_cleaned_phone ON users (regexp_replace(phone, '\D', '', 'g'));
    
  • 测试验证:先在测试环境用小样本验证逻辑,重点确认关联数据迁移、号码保留规则的正确性,避免线上数据损坏。

内容的提问来源于stack exchange,提问作者ra-11

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:25:17