Files
users/开发文档/6、后端/MongoDB连接器核心.md

3.0 KiB
Raw Blame History

神射手 - MongoDB连接器核心

📅 从 lib/mongodb.ts 提取 | 2026-01-31


一、连接配置

// lib/mongodb.ts
const MONGODB_URI = process.env.MONGODB_URI || 
  'mongodb://admin:admin123@localhost:27017/?authSource=admin'

const DB_NAMES = {
  KR: 'KR',
  KR_腾讯: 'KR_腾讯',
  KR_微博: 'KR_微博',
  KR_京东: 'KR_京东',
  KR_存客宝: 'KR_存客宝',
  KR_点了码: 'KR_点了码'
}

二、核心函数

2.1 连接池

let cachedClient: MongoClient | null = null

export async function getMongoClient(): Promise<MongoClient> {
  if (cachedClient) return cachedClient
  const client = new MongoClient(MONGODB_URI, {
    maxPoolSize: 10,
    minPoolSize: 2,
    maxIdleTimeMS: 60000,
    serverSelectionTimeoutMS: 5000,
  })
  await client.connect()
  cachedClient = client
  return client
}

2.2 手机号归一化

function normalizePhone(phone: string): string[] {
  const cleaned = phone.replace(/\D/g, '')
  const variants: string[] = []
  if (cleaned.startsWith('86') && cleaned.length === 13) {
    const base = cleaned.slice(2)
    variants.push(base, `+86${base}`, `86${base}`, cleaned)
  } else if (cleaned.length === 11 && cleaned.startsWith('1')) {
    variants.push(cleaned, `+86${cleaned}`, `86${cleaned}`)
  } else {
    variants.push(phone, cleaned)
  }
  return [...new Set(variants)]
}

2.3 跨库查询用户画像

export async function queryFullProfile(phone: string) {
  const client = await getMongoClient()
  const phoneVariants = normalizePhone(phone)
  const query = { $or: phoneVariants.map(p => ({ phone: p })) }
  
  const [valuation, qqPhone, ckbAsset] = await Promise.all([
    client.db('KR').collection('用户估值').findOne(query),
    client.db('KR_腾讯').collection('QQ+手机').findOne(query),
    client.db('KR_存客宝').collection('用户资产统一视图').findOne(query).catch(() => null)
  ])
  
  return { valuation, qqPhone, ckbAsset }
}

2.4 智能搜索QQ→手机→画像

export async function intelligentSearch(query: string) {
  // QQ号: 先查 KR_腾讯 获取手机号,再查 KR.用户估值
  if (/^\d{5,11}$/.test(query)) {
    const qqDoc = await client.db('KR_腾讯').collection('QQ+手机').findOne({
      $or: [{ qq: query }, { qq: parseInt(query) }]
    })
    if (qqDoc?.phone) {
      return queryFullProfile(qqDoc.phone)
    }
  }
  // 手机号: 直接 queryFullProfile
  // 关键词: name/city/province 模糊搜索
}

三、接口定义

interface UserValuationDoc {
  phone?: string
  phone_masked?: string
  name?: string
  user_level?: string
  user_evaluation_score?: number
  province?: string
  city?: string
  tags?: string[]
}

interface QQPhoneDoc {
  qq: string
  phone?: string
  手机号?: string
  省份?: string
  运营商?: string
}

四、关联文档