132 lines
3.0 KiB
Markdown
132 lines
3.0 KiB
Markdown
# 神射手 - MongoDB连接器核心
|
||
|
||
> 📅 从 lib/mongodb.ts 提取 | 2026-01-31
|
||
|
||
---
|
||
|
||
## 一、连接配置
|
||
|
||
```typescript
|
||
// 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 连接池
|
||
|
||
```typescript
|
||
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 手机号归一化
|
||
|
||
```typescript
|
||
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 跨库查询用户画像
|
||
|
||
```typescript
|
||
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→手机→画像)
|
||
|
||
```typescript
|
||
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 模糊搜索
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、接口定义
|
||
|
||
```typescript
|
||
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
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、关联文档
|
||
|
||
- [后端开发规范.md](./后端开发规范.md)
|
||
- [../7、数据库/ER与查询逻辑.md](../7、数据库/ER与查询逻辑.md)
|