Taimoor Ahmad
Taimoor Ahmad

Reputation: 549

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:

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

Upvotes: 0

Views: 133

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17858

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
}

Upvotes: 1

Miguel Medellín
Miguel Medellín

Reputation: 11

Model

const redirectionSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
    },
    pairs: [
        {
            _id: false,
            code: { type: String },
            site: { type: String }
        }
    ],
    date: {
        type: Date,
        required: true,
        default: Date.now
    }
})

const Redirection = mongoose.model('Redirection', redirectionSchema);

Use

const redirection = new Redirection({
    username: "taimoor",
    pairs: [
        {
            code: "CA",
            site: "google.ca"
        },
        {
            code: "US",
            site: "google.com"
        },
        {
            code: "GB",
            site: "google.co.uk"
        }
    ],
    date: new Date(1574880349),
})

redirection.save();

Example database output

{
  "_id": {
    "$oid": "5ddecc4c6dd3760c40ff354b"
  },
  "username": "taimoor",
  "pairs": [
    {
      "code": "CA",
      "site": "google.ca"
    },
    {
      "code": "US",
      "site": "google.com"
    },
    {
      "code": "GB",
      "site": "google.co.uk"
    }
  ],
  "date": {
    "$date": "1970-01-19T05:28:00.349Z"
  },
  "__v": 0
}

Upvotes: 1

Related Questions