hulai-website/scripts/auto-tag-reviews.mjs

68 行
3.2 KiB
JavaScript

#!/usr/bin/env node
/**
* 基于评价正文关键词,自动回填 reviews.scenes 和 reviews.concerns。
* 仅在字段为空时写入,已人工打过的保留。
*/
import Database from 'better-sqlite3'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const DB = join(dirname(fileURLToPath(import.meta.url)), '../server/database/hulai.db')
// 场景词表:关键词命中 → 标签
const SCENE_RULES = [
{ tag: '亲子', kws: ['孩子', '小朋友', '娃', '宝宝', '女儿', '儿子', '孩儿', '带娃'] },
{ tag: '家庭出游', kws: ['全家', '一家', '家人', '爸妈', '父母', '夫妻'] },
{ tag: '带老人', kws: ['老人', '父母', '爸妈', '长辈', '外婆', '奶奶', '爷爷', '姥姥'] },
{ tag: '蜜月', kws: ['蜜月', '度蜜月', '情侣'] },
{ tag: '摄影', kws: ['旅拍', '拍照', '摄影', '出片', '壁纸'] },
{ tag: '毕业游', kws: ['毕业', '升学', '小升初', '幼升小'] },
{ tag: '多家庭', kws: ['两个家庭', '三家', '朋友一起', '两家', '同行', '大团', '几家', '好友', '闺蜜', '同伴', '一起出行', '结伴'] },
]
// 关心维度词表
const CONCERN_RULES = [
{ tag: '领队服务', kws: ['领队', '师傅', '司机', '导游', '贴心', '耐心', '细心'] },
{ tag: '行程安排', kws: ['行程', '安排', '线路', '路线', '节奏'] },
{ tag: '住宿体验', kws: ['住宿', '酒店', '民宿', '房间', '房'] },
{ tag: '摄影旅拍', kws: ['旅拍', '拍照', '摄影', '出片', '服饰'] },
{ tag: '错峰不排队', kws: ['错峰', '不排队', '避开', '人少', '小众', '清净', '避人', '安静', '没有人', '没什么人'] },
{ tag: '性价比', kws: ['性价比', '值得', '划算', '物超所值', '实惠', '不贵', '合适', '值', '不亏'] },
{ tag: '安全放心', kws: ['安全', '放心', '安心', '靠谱', '信任'] },
{ tag: '特色体验', kws: ['骑马', '越野车', '营地', '烧烤', '滑草', '漂流', '卡丁车'] },
{ tag: '饮食', kws: ['吃', '餐', '美食', '饭菜', '零食', '水果'] },
]
function tagsFor(content, rules) {
const out = []
for (const { tag, kws } of rules) {
if (kws.some(k => content.includes(k))) out.push(tag)
}
return out
}
const db = new Database(DB)
const rows = db.prepare('SELECT id, content, scenes, concerns FROM reviews').all()
const upd = db.prepare('UPDATE reviews SET scenes = ?, concerns = ? WHERE id = ?')
let touched = 0
const tx = db.transaction(() => {
for (const r of rows) {
const c = r.content || ''
upd.run(JSON.stringify(tagsFor(c, SCENE_RULES)), JSON.stringify(tagsFor(c, CONCERN_RULES)), r.id)
touched++
}
})
tx()
console.log(`更新了 ${touched} / ${rows.length} 条评价的场景/关心点标签`)
// 统计
const allScenes = new Set()
const allConcerns = new Set()
for (const r of db.prepare('SELECT scenes, concerns FROM reviews').all()) {
try { JSON.parse(r.scenes || '[]').forEach(x => allScenes.add(x)) } catch {}
try { JSON.parse(r.concerns || '[]').forEach(x => allConcerns.add(x)) } catch {}
}
console.log('场景标签:', [...allScenes].join(' · '))
console.log('关心维度:', [...allConcerns].join(' · '))