You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 || '',
});

核心问题分析

  1. Schema结构不匹配:API返回的是comments数组(包含用户评论和开发者评论),但现有Schema直接定义了顶级的userComment,无法对应嵌套数组结构。
  2. 赋值语法错误:对象字面量中不能直接写userComment.lastModified,必须使用嵌套对象的赋值方式。
  3. 未处理嵌套时间字段: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:45:25