annyang.js与MongoDB集成:存储语音交互数据

【免费下载链接】annyang TalAter/annyang: 是一个用于语音识别的 JavaScript 库。适合在网页中添加语音识别功能。特点是提供了简单的 API,支持多种语音识别引擎,并且可以自定义识别语言和行为。 【免费下载链接】annyang 项目地址: https://gitcode.com/gh_mirrors/an/annyang

你是否在开发语音交互应用时遇到过数据存储难题?用户的每一次语音指令都蕴含着宝贵的用户行为信息,但如何高效捕获、存储并分析这些数据却常常让人头疼。本文将带你一步实现annyang.js语音识别数据与MongoDB数据库的无缝对接,让你轻松掌握语音交互数据的全生命周期管理。

读完本文你将学会:

  • 配置annyang.js捕获语音指令及上下文数据
  • 创建Node.js后端服务接收语音数据
  • 设计MongoDB数据模型存储交互记录
  • 实现前后端数据加密传输与安全存储
  • 构建基础的数据查询与分析功能

技术架构概览

语音交互数据存储系统主要包含三个核心组件:前端语音识别、后端数据处理和数据库存储。以下是系统架构的流程图:

mermaid

核心技术栈包括:

  • 前端:annyang.js语音识别库(src/annyang.js)
  • 后端:Node.js + Express框架
  • 数据库:MongoDB
  • 传输:HTTPS加密协议

准备工作

环境搭建

首先确保你的开发环境中已安装Node.js和MongoDB。然后通过以下命令克隆项目仓库:

git clone https://gitcode.com/gh_mirrors/an/annyang
cd annyang
npm install

项目目录结构中,我们主要关注这些文件:

依赖安装

安装项目所需依赖包:

# 安装Express和MongoDB驱动
npm install express mongoose dotenv cors

# 安装开发依赖
npm install nodemon --save-dev

前端实现:捕获语音交互数据

配置annyang.js

修改demo/index.html文件,添加必要的HTML元素和JavaScript代码。首先在页面中添加语音状态指示和控制按钮:

<div class="voice-controls">
  <button id="startBtn" class="control-btn">开始监听</button>
  <button id="stopBtn" class="control-btn" disabled>停止监听</button>
  <div id="status" class="status-indicator">就绪</div>
  <div id="transcriptBox" class="transcriptBox"></div>
</div>

扩展语音数据捕获功能

demo/index.html中添加JavaScript代码,配置annyang.js捕获语音数据并发送到后端:

// 初始化annyang
if (annyang) {
  // 配置语音命令
  const commands = {
    '搜索 *query': handleSearch,
    '显示 *page': handleNavigation,
    '设置 *option 为 *value': handleSettings,
    '计算 *expression': handleCalculation,
    '*anything': handleUnknownCommand
  };
  
  // 添加命令
  annyang.addCommands(commands);
  
  // 添加回调函数捕获识别结果
  annyang.addCallback('resultMatch', handleResultMatch);
  annyang.addCallback('resultNoMatch', handleResultNoMatch);
  annyang.addCallback('error', handleError);
  
  // 调试模式
  annyang.debug(true);
}

// 处理匹配到的语音命令
function handleResultMatch(userSaid, commandText, phrases) {
  const interactionData = {
    command: commandText,
    transcript: userSaid,
    alternatives: phrases,
    timestamp: new Date().toISOString(),
    success: true,
    userId: 'anonymous', // 在实际应用中应使用真实用户ID
    sessionId: generateSessionId(),
    deviceInfo: getDeviceInfo()
  };
  
  // 显示识别结果
  displayTranscript(userSaid, true);
  
  // 发送数据到后端
  sendVoiceData(interactionData);
}

数据发送函数实现

添加数据发送到后端的函数:

// 发送语音数据到后端
async function sendVoiceData(data) {
  try {
    const response = await fetch('http://localhost:3000/api/voice-interactions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });
    
    if (!response.ok) {
      throw new Error('网络响应不正常');
    }
    
    const result = await response.json();
    console.log('数据已保存:', result);
  } catch (error) {
    console.error('发送数据时出错:', error);
    // 实现本地存储失败的数据,稍后重试
    storeFailedDataLocally(data);
  }
}

后端实现:构建数据接收服务

创建Express服务器

在项目根目录创建server文件夹,并添加server/index.js文件:

require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const VoiceInteraction = require('./models/VoiceInteraction');

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json());

// 连接MongoDB数据库
mongoose.connect(process.env.MONGODB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('MongoDB连接成功'))
.catch(err => console.error('MongoDB连接失败:', err));

// API路由
app.post('/api/voice-interactions', async (req, res) => {
  try {
    const interaction = new VoiceInteraction(req.body);
    await interaction.save();
    res.status(201).json({ 
      success: true, 
      message: '交互数据已保存',
      id: interaction._id 
    });
  } catch (error) {
    res.status(400).json({ 
      success: false, 
      message: '保存数据失败',
      error: error.message 
    });
  }
});

// 获取交互历史
app.get('/api/voice-interactions', async (req, res) => {
  try {
    const interactions = await VoiceInteraction.find()
      .sort({ timestamp: -1 })
      .limit(50);
      
    res.json(interactions);
  } catch (error) {
    res.status(500).json({ 
      success: false, 
      message: '获取数据失败',
      error: error.message 
    });
  }
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

定义MongoDB数据模型

创建server/models/VoiceInteraction.js文件,定义数据模型:

const mongoose = require('mongoose');

const voiceInteractionSchema = new mongoose.Schema({
  command: {
    type: String,
    required: true,
    trim: true
  },
  transcript: {
    type: String,
    required: true,
    trim: true
  },
  alternatives: {
    type: [String],
    default: []
  },
  timestamp: {
    type: Date,
    required: true,
    default: Date.now
  },
  success: {
    type: Boolean,
    required: true
  },
  userId: {
    type: String,
    required: true,
    trim: true
  },
  sessionId: {
    type: String,
    required: true,
    trim: true,
    index: true
  },
  deviceInfo: {
    browser: String,
    os: String,
    device: String,
    screenSize: String
  },
  location: {
    // 可选的地理位置信息
    type: {
      type: String,
      enum: ['Point'],
      default: undefined
    },
    coordinates: {
      type: [Number],
      default: undefined
    }
  },
  processingTime: Number // 处理时间(毫秒)
}, {
  timestamps: true,
  collection: 'voiceInteractions'
});

// 添加索引以提高查询性能
voiceInteractionSchema.index({ userId: 1, timestamp: -1 });
voiceInteractionSchema.index({ timestamp: -1 });

module.exports = mongoose.model('VoiceInteraction', voiceInteractionSchema);

配置环境变量

创建.env文件存储敏感配置信息:

# 服务器配置
PORT=3000
NODE_ENV=development

# MongoDB配置
MONGODB_URI=mongodb://localhost:27017/voiceInteractionsDB

# 安全配置
API_KEY=your_secure_api_key_here

后端服务实现

创建服务器入口文件

创建server.js作为后端服务入口:

require('dotenv').config();
const app = require('./server/index');

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});

添加数据验证中间件

创建server/middleware/validateInteraction.js实现数据验证:

const { body, validationResult } = require('express-validator');

// 验证语音交互数据
const validateVoiceInteraction = [
  body('command').trim().notEmpty().withMessage('命令不能为空'),
  body('transcript').trim().notEmpty().withMessage('语音转录文本不能为空'),
  body('userId').trim().notEmpty().withMessage('用户ID不能为空'),
  body('sessionId').trim().notEmpty().withMessage('会话ID不能为空'),
  body('success').isBoolean().withMessage('success必须是布尔值'),
  
  // 验证结果处理
  (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ success: false, errors: errors.array() });
    }
    next();
  }
];

module.exports = { validateVoiceInteraction };

数据库操作与查询

创建数据访问层

创建server/services/interactionService.js封装数据库操作:

const VoiceInteraction = require('../models/VoiceInteraction');

// 保存语音交互数据
async function saveInteraction(data) {
  const interaction = new VoiceInteraction(data);
  return await interaction.save();
}

// 获取用户交互历史
async function getUserInteractions(userId, limit = 50) {
  return await VoiceInteraction.find({ userId })
    .sort({ timestamp: -1 })
    .limit(limit);
}

// 获取会话交互记录
async function getSessionInteractions(sessionId) {
  return await VoiceInteraction.find({ sessionId })
    .sort({ timestamp: 1 });
}

// 统计常用命令
async function getPopularCommands(limit = 10, days = 30) {
  const date = new Date();
  date.setDate(date.getDate() - days);
  
  return await VoiceInteraction.aggregate([
    { $match: { timestamp: { $gte: date } } },
    { $group: { _id: '$command', count: { $sum: 1 } } },
    { $sort: { count: -1 } },
    { $limit: limit }
  ]);
}

module.exports = {
  saveInteraction,
  getUserInteractions,
  getSessionInteractions,
  getPopularCommands
};

添加统计分析API

server/routes/stats.js中添加统计分析接口:

const express = require('express');
const router = express.Router();
const interactionService = require('../services/interactionService');

// 获取常用命令统计
router.get('/popular-commands', async (req, res) => {
  try {
    const { limit = 10, days = 30 } = req.query;
    const stats = await interactionService.getPopularCommands(
      parseInt(limit), 
      parseInt(days)
    );
    
    res.json({
      success: true,
      data: stats
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取统计数据失败',
      error: error.message
    });
  }
});

// 获取每日交互量
router.get('/daily-volume', async (req, res) => {
  try {
    const { days = 30 } = req.query;
    const date = new Date();
    date.setDate(date.getDate() - days);
    
    const result = await VoiceInteraction.aggregate([
      { $match: { timestamp: { $gte: date } } },
      { $group: {
          _id: { 
            year: { $year: '$timestamp' },
            month: { $month: '$timestamp' },
            day: { $dayOfMonth: '$timestamp' }
          },
          count: { $sum: 1 }
        }
      },
      { $sort: { '_id.year': 1, '_id.month': 1, '_id.day': 1 } }
    ]);
    
    // 格式化结果
    const formattedResult = result.map(item => ({
      date: `${item._id.year}-${item._id.month.toString().padStart(2, '0')}-${item._id.day.toString().padStart(2, '0')}`,
      interactions: item.count
    }));
    
    res.json({
      success: true,
      data: formattedResult
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取统计数据失败',
      error: error.message
    });
  }
});

module.exports = router;

系统集成与测试

启动服务与测试流程

添加启动脚本到package.json

"scripts": {
  "start": "node server.js",
  "dev": "nodemon server.js",
  "test": "echo \"Error: no test specified\" && exit 1"
}

启动MongoDB和应用服务:

# 启动MongoDB
mongod --dbpath /path/to/your/database

# 启动后端服务
npm run dev

# 打开示例页面
open demo/index.html

验证数据流程

使用浏览器打开demo/index.html,点击"开始监听"按钮,说出一些指令如"搜索天气"、"显示设置"等,然后检查MongoDB数据库中是否成功存储了交互数据:

# 进入MongoDB命令行
mongo

# 查询数据库
use voiceInteractionsDB
db.voiceInteractions.find().pretty()

应用场景与扩展

数据分析与可视化

基于收集的语音交互数据,我们可以构建各种分析功能:

  1. 用户行为分析:了解用户常用命令和交互模式
  2. 语音识别优化:分析识别失败案例,改进命令设计
  3. 用户体验提升:根据使用频率优化界面和交互流程

可以使用Chart.js或D3.js在前端构建数据可视化仪表盘,展示关键指标和趋势。

高级功能扩展

  1. 实时分析:集成Socket.io实现语音数据实时分析和推送
  2. 自然语言处理:添加NLP服务分析用户意图和情感
  3. 个性化推荐:基于用户语音习惯提供个性化功能推荐
  4. 多语言支持:利用src/annyang.js的语言设置功能,添加多语言支持

语音交互分析仪表盘

总结与最佳实践

通过本文的实现,我们构建了一个完整的语音交互数据收集和存储系统。关键要点包括:

  1. 数据完整性:捕获足够的上下文信息,包括时间戳、会话ID和设备信息
  2. 安全性:确保用户数据加密传输和安全存储,敏感信息需脱敏处理
  3. 性能优化:合理设计数据库索引,优化查询性能
  4. 可扩展性:模块化设计便于添加新功能和集成其他服务

官方文档:docs/FAQ.md提供了更多关于annyang.js的高级用法和故障排除指南。社区教程:README.md包含项目的基本介绍和快速启动指南。

要进一步提升系统,可以考虑实现数据备份策略、添加数据访问权限控制和开发更丰富的数据分析功能。语音交互数据是用户体验优化的宝贵资源,合理利用这些数据将为你的应用带来显著的竞争力提升。

希望本文能帮助你构建更强大的语音交互应用,如有任何问题或建议,请参考项目文档或提交issue。

【免费下载链接】annyang TalAter/annyang: 是一个用于语音识别的 JavaScript 库。适合在网页中添加语音识别功能。特点是提供了简单的 API,支持多种语音识别引擎,并且可以自定义识别语言和行为。 【免费下载链接】annyang 项目地址: https://gitcode.com/gh_mirrors/an/annyang

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐