Home > Software engineering >  Mongoose: Array with 2 different nested schemas as key-value
Mongoose: Array with 2 different nested schemas as key-value

Time:01-31

I'm trying to insert data from Google Reply to Reviews API into MongoDb using mongoose but some of the objects inserted have empty fields and some of them are nested key-value objects inside an Array which I don't know how to catch.

This is the JSON response from the API:

{
  "reviews": [
    {
      "reviewId": "19940672-2a0f-470b-8760-05ce91add518",
      "authorName": "el piculin 357",
      "comments": [
        {
          "userComment": {
            "text": "\tEs bueno y los logos son faciles de adivinar",
            "lastModified": {
              "seconds": "1675041753",
              "nanos": 386000000
            },
            "starRating": 5,
            "reviewerLanguage": "es",
            "device": "grandpplte",
            "androidOsVersion": 23,
            "appVersionCode": 99,
            "appVersionName": "2.5.0",
            "deviceMetadata": {
              "productName": "grandpplte (Galaxy J2 Prime)",
              "manufacturer": "Samsung",
              "deviceClass": "FORM_FACTOR_PHONE",
              "screenWidthPx": 540,
              "screenHeightPx": 960,
              "nativePlatform": "ABI_ARM_V7,ABI_ARM",
              "screenDensityDpi": 240,
              "glEsVersion": 196609,
              "ramMb": 1407
            }
          }
        }
      ]
    }
  ]
}

This is my Schema (review.model.js):

const mongoose = require("mongoose");

const ReviewSchema = new mongoose.Schema({
  reviewId: { type: String, default: '', unique: true },
  authorName: { type: String, default: '' },
  userComment: {
      text: { type: String, default: '' },
      lastModified: {
          seconds: { type: String, default: '' },
          nanos: { type: Number, default: 0 },
      },
      starRating: { type: Number, default: 0 },
      reviewerLanguage: { type: String, default: '' },
      device: { type: String, default: '' },
      androidOsVersion: { type: Number, default: 0 },
      appVersionCode: { type: Number, default: 0 },
      appVersionNumber: { type: String, default: '' },
      thumbsUpCount: { type: Number, default: 0 },
      thumbsDownCount: { type: Number, default: 0 },
  },
  developerComment: {
      text: { type: String, default: '' },
      lastModified: {
          seconds: { type: String, default: '' },
          nanos: { type: Number, default: 0 },
      }
  },
  appInformation: {
      packageIdentifier: { type: String, default: '' }
  }
});

const Review = mongoose.model("Review", ReviewSchema);

module.exports = Review;

Another thing that I tried:

const mongoose = require("mongoose");

const AppInformationSchema = new mongoose.Schema({
    packageIdentifier: { type: String, default: '' }
});

const DeveloperCommentSchema = new mongoose.Schema({
    text: { type: String, default: '' },
    lastModified: { LastModifiedSchema }
});

const LastModifiedSchema = new mongoose.Schema({
    seconds: { type: String, default: '' },
    nanos: { type: Number, default: 0 },
});

const UserCommentScehma = new mongoose.Schema({
    text: { type: String, default: '' },
    lastModified: { type: LastModifiedSchema },
    starRating: { type: Number, default: 0 },
    reviewerLanguage: { type: String, default: '' },
    device: { type: String, default: '' },
    androidOsVersion: { type: Number, default: 0 },
    appVersionCode: { type: Number, default: 0 },
    appVersionNumber: { type: String, default: '' },
    thumbsUpCount: { type: Number, default: 0 },
    thumbsDownCount: { type: Number, default: 0 }
});

const ReviewSchema = new mongoose.Schema({
    reviewId: { type: String, default: '', unique: true },
    authorName: { type: String, default: '' },
    comments: [UserCommentScehma, DeveloperCommentSchema],
    appInformation: { AppInformationSchema }
});

const Review = mongoose.model("Review", ReviewSchema);

module.exports = Review;

But I get an error when trying to implement it like that:

ReferenceError: Cannot access 'LastModifiedSchema' before initialization

What is the right way of implementing it?

CodePudding user response:

As UserCommentScehma is under userComment itself, so you need to consider this structure in the schema as well.

const ReviewSchema = new mongoose.Schema({
    reviewId: { type: String, default: '', unique: true },
    authorName: { type: String, default: '' },
    comments: [{ userComment: UserCommentScehma }, DeveloperCommentSchema],
    appInformation: { AppInformationSchema }
});
  • Related