Search code examples
mongodbmongoosenosqlschemamongoose-schema

Node, Express, MongoDB: Creating a schema with an array of objects?


Here's my desired schema:

{
    username: "taimoor",
    pairs: [
        {
            code: "CA",
            site: "google.ca"
        },
        {
            code: "US",
            site: "google.com"
        },
        {
            code: "GB",
            site: "google.co.uk"
        }
    ]
    date: 1574880349,
}

Here's my current schema:

const redirectionSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
    },
    pairs: [
        // What do I place here?
    ],
    date: {
        type: Date,
        required: true,
        default: Date.now
    }
})

I don't know how to proceed and implement this using mongoose. Should I create another schema called Pair? And if so:

  • How do I ensure the pairs will be valid?
  • How do I add a Pair to "pairs" programmatically?

Thanks for your time, this is my first time using NoSQL.


Solution

  • You need to have an inner schema for pairs. This way you can apply required or other validations to the pairs.

    const mongoose = require("mongoose");
    
    const redirectionSchema = new mongoose.Schema({
      username: {
        type: String,
        required: true
      },
      pairs: [
        new mongoose.Schema({
          code: {
            type: String,
            required: true
          },
          site: {
            type: String,
            required: true
          }
        })
      ],
      date: {
        type: Date,
        required: true,
        default: Date.now
      }
    });
    
    module.exports = mongoose.model("Redirect", redirectionSchema);
    

    And you can use the following App.js to create a document with username and pairs, or add another pair to an existing document.

    App.js

    const express = require("express");
    const app = express();
    const mongoose = require("mongoose");
    const Redirect = require("./models/redirect");
    const url = "mongodb://localhost:27017/redirectDB";
    
    const port = process.env.PORT || 3000;
    
    app.use(express.json());
    
    mongoose
      .connect(url, {
        useNewUrlParser: true,
        useUnifiedTopology: true
      })
      .then(() => {
        app.listen(port, () => {
          console.log(`App running on port ${port}...`);
        });
      })
      .catch(error => console.log(error));
    
    app.post("/redirect", async (req, res) => {
      try {
        const result = await Redirect.create(req.body);
        res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }
    });
    
    app.post("/redirect/:id/pair", async (req, res) => {
      const { code, site } = req.body;
    
      try {
        const result = await Redirect.findByIdAndUpdate(
          req.params.id,
          {
            $push: {
              pairs: { code, site }
            }
          },
          { new: true }
        );
    
        res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }
    });
    

    To create username and pairs send a post requrest to the url http://localhost:3000/redirect like this:

    {
        "username": "taimoor",
        "pairs": [
            {
                "code": "CA",
                "site": "google.ca"
            },
            {
                "code": "US",
                "site": "google.com"
            }
        ]
    }
    

    The response will be like this:

    {
        "_id": "5ddecfcb3cd5c035b4c31d95",
        "username": "taimoor",
        "pairs": [
            {
                "_id": "5ddecfcb3cd5c035b4c31d97",
                "code": "CA",
                "site": "google.ca"
            },
            {
                "_id": "5ddecfcb3cd5c035b4c31d96",
                "code": "US",
                "site": "google.com"
            }
        ],
        "date": "2019-11-27T19:34:35.781Z",
        "__v": 0
    }
    

    And later we can add a new pair to this document using a post request to this url http://localhost:3000/redirect/5ddecfcb3cd5c035b4c31d95/pair. The id in the url is the id we previosuly created, and got in the response.

    Request:

    {
        "code": "GB",
        "site": "google.co.uk"
    }
    

    Response:

    {
        "_id": "5ddecfcb3cd5c035b4c31d95",
        "username": "taimoor",
        "pairs": [
            {
                "_id": "5ddecfcb3cd5c035b4c31d97",
                "code": "CA",
                "site": "google.ca"
            },
            {
                "_id": "5ddecfcb3cd5c035b4c31d96",
                "code": "US",
                "site": "google.com"
            },
            {
                "_id": "5dded01693be502168a0f794",
                "code": "GB",
                "site": "google.co.uk"
            }
        ],
        "date": "2019-11-27T19:34:35.781Z",
        "__v": 0
    }