NestJS中使用Mongoose解析Google API嵌套JSON的问题求助
解决NestJS中Google API响应解析到Mongoose的嵌套对象问题
问题背景
需要将Google API返回的评论数据解析并存储到Mongoose中,API返回的JSON结构如下:
{ "reviewId": "f1a0ec26-9aca-424f-8b05-cff6aa3d2337", "authorName": "Some User", "comments": [ { "userComment": { "text": "Amazing!", "lastModified": { "seconds": "1659685904" }, "starRating": 5, "reviewerLanguage": "en" } }, { "developerComment": { "text": "Thank you.", "lastModified": { "seconds": "1659688852" } } } ] }
当前使用的Mongoose Schema和赋值代码存在问题,导致userComment.lastModified赋值报错,现有Schema如下:
import * as mongoose from 'mongoose'; export interface Review extends mongoose.Document { authorName: string; reviewId: string; userComment: { text: string; lastModified: string; starRating: number; reviewerLanguage: string; }; } export const ReviewSchema = new mongoose.Schema({ authorName: { type: String, required: true }, reviewId: { type: String, index: { unique: true }, required: true }, userComment: { text: { type: String, required: false }, lastModified: { type: String, required: false }, starRating: { type: Number, required: false }, reviewerLanguage: { type: String, required: false }, }, });
错误的赋值代码:
const newReview = new this.reviewModel({ authorName: review.authorName || 'NO_NAME', reviewId: review.reviewId || 'NO_ID', userComment.lastModified: review.userComment[0].lastModified || '', });
核心问题分析
- Schema结构不匹配:API返回的是
comments数组(包含用户评论和开发者评论),但现有Schema直接定义了顶级的userComment,无法对应嵌套数组结构。 - 赋值语法错误:对象字面量中不能直接写
userComment.lastModified,必须使用嵌套对象的赋值方式。 - 未处理嵌套时间字段:API的
lastModified是包含seconds的对象,直接赋值会导致存储结构不符合预期。
正确实现步骤
1. 调整Mongoose Schema以匹配API结构
根据API的嵌套数组结构,定义对应的子Schema和主Schema:
import * as mongoose from 'mongoose'; // 用户评论子Schema const UserCommentSchema = new mongoose.Schema({ text: { type: String, required: false }, lastModified: { type: String, required: false }, starRating: { type: Number, required: false }, reviewerLanguage: { type: String, required: false }, }); // 开发者评论子Schema const DeveloperCommentSchema = new mongoose.Schema({ text: { type: String, required: false }, lastModified: { type: String, required: false }, }); // 评论项Schema(对应comments数组的单个元素) const CommentItemSchema = new mongoose.Schema({ userComment: { type: UserCommentSchema, required: false }, developerComment: { type: DeveloperCommentSchema, required: false }, }); // 主Review接口 export interface Review extends mongoose.Document { authorName: string; reviewId: string; comments: Array<{ userComment?: { text: string; lastModified: string; starRating: number; reviewerLanguage: string; }; developerComment?: { text: string; lastModified: string; }; }>; } // 主Review Schema export const ReviewSchema = new mongoose.Schema({ authorName: { type: String, required: true }, reviewId: { type: String, index: { unique: true }, required: true }, comments: { type: [CommentItemSchema], required: false }, });
2. 正确解析API响应并创建文档
处理API返回的数据,转换为符合Schema的结构,同时修正赋值语法:
// 解析comments数组,转换时间字段格式 const parsedComments = review.comments.map(comment => { const processed: any = {}; if (comment.userComment) { processed.userComment = { text: comment.userComment.text, // 将秒数转换为ISO时间字符串,也可直接存储秒数字符串 lastModified: new Date(parseInt(comment.userComment.lastModified.seconds) * 1000).toISOString(), starRating: comment.userComment.starRating, reviewerLanguage: comment.userComment.reviewerLanguage }; } if (comment.developerComment) { processed.developerComment = { text: comment.developerComment.text, lastModified: new Date(parseInt(comment.developerComment.lastModified.seconds) * 1000).toISOString() }; } return processed; }); // 创建并保存Review文档 const newReview = new this.reviewModel({ authorName: review.authorName || 'NO_NAME', reviewId: review.reviewId || 'NO_ID', comments: parsedComments }); await newReview.save();
3. 如果仅需提取用户评论的简化写法
若不需要存储开发者评论,可调整Schema只保留userComment,同时修正赋值语法:
// 调整后的简化Schema export interface Review extends mongoose.Document { authorName: string; reviewId: string; userComment: { text: string; lastModified: string; starRating: number; reviewerLanguage: string; }; } export const ReviewSchema = new mongoose.Schema({ authorName: { type: String, required: true }, reviewId: { type: String, index: { unique: true }, required: true }, userComment: { text: { type: String, required: false }, lastModified: { type: String, required: false }, starRating: { type: Number, required: false }, reviewerLanguage: { type: String, required: false }, }, }); // 简化的赋值代码 const userComment = review.comments.find(c => c.userComment)?.userComment; const newReview = new this.reviewModel({ authorName: review.authorName || 'NO_NAME', reviewId: review.reviewId || 'NO_ID', userComment: userComment ? { text: userComment.text, lastModified: new Date(parseInt(userComment.lastModified.seconds) * 1000).toISOString(), starRating: userComment.starRating, reviewerLanguage: userComment.reviewerLanguage } : {} }); await newReview.save();
内容的提问来源于stack exchange,提问作者ytpm
相关产品推荐
相关产品推荐

