1-n, 1-1
https://stackoverflow.com/questions/32038793/one-to-one-relationship-with-mongoose
First of all, there is a huge difference between relationships in MongoDB and those in SQL based datastores (you need to be clear about this from the get-go).
Relationships in MongoDB are just representations of related data. There is no mechanism which maintains the integrity of these relationships.
What mongoose does with refs is just use the field having the ref option to query the _id field of documents in the referenced collection. This is used for operations like populate (which internally calls findById queries on the target collection and replaces the referenced field with the documents).
This being cleared, you can store one or many IDs for the referenced collection in the field, thus creating one-to-one or one-to-many “relationships”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
'use strict'; console.log("creating schema object..."); var mongoose = require('mongoose'); var Schema = mongoose.Schema; // event attendee var eventAttendee = new mongoose.Schema({ phone: {type: String}, name: {type: String}, registered: Boolean }); // event location var location = new mongoose.Schema({ address: {type: String}, city: {type: String}, province: {type: String}, zip: {type: String} }); module.exports = mongoose.model('Events', new Schema({ Event_Title: {type: String}, Event_Description: {type: String}, Event_Date: {type: Date, default: Date.now}, Event_Location: {type:location, default:null}, // 1 to 1 Created_Date: {type: Date, default: Date.now}, Author: {type: String}, attendees: [eventAttendee] // 1 to n }, {collection: "funEvents"})); console.log("Attach our schema object to string 'Events', Then register it as a model"); |
Add the event
1 2 3 |
app.route('/events') .get(eventList.list_all_events) .post(eventList.create_event); |
Open up postman. select POST. In the the url, type in http://localhost/events
In Node express code, we have stated that for post verbs at url /events, we want it to hit create_event function. And create_event function is where we implement getting the data from the body object, and saving it into the database.
Then check the database to verify.
1 |
{ "_id" : ObjectId("5a2f3f9b8f4a4a4367dbf59e"), "Event_Title" : "Super Badminton", "Event_Description" : "Play some badminton with fellow friends", "Author" : "Ricky T", "attendees" : [ ], "Created_Date" : ISODate("2017-12-12T02:31:55.180Z"), "Event_Location" : null, "Event_Date" : ISODate("2017-12-12T02:31:55.180Z"), "__v" : 0 } |
Look at the object id 5a2f3f9b8f4a4a4367dbf59e. We use this as the event id that we will be adding attendees to.
Add attendee(s) to the event (1 to n)
In order to register the attendee, we use postman.
given the route code:
1 2 |
app.route('/events/:eventId/:phoneId') .post(eventList.registerAttendee); |
we do the following.
web verb: POST
url: http://localhost/events/5a2f3f9b8f4a4a4367dbf59e
Notice that the last param is a phoneId. We just give a phone number like so:
url: http://localhost/events/5a2f3f9b8f4a4a4367dbf59e/13510083852
When the user put this in the browser, it will hit the registerAttendee function in node express. The registerAttendee function will look for name and phone in its request object’s body:
1 |
event.attendees.push(createAttendeeObject(req.body.phone,req.body.name)); |
Hence, as we can see, it gets the properties phone and name from the body, create an object out of it, and pushes it onto the attendees’ array property.
So in your post man, click on body, highlight x-www-form-urlencoded, and enter key/values:
name: Hannah Hong
phone: 135103483252
Essentially, we are entering the properties that are needed by the eventAttendee schema:
1 2 3 4 5 6 |
// event attendee var eventAttendee = new mongoose.Schema({ phone: {type: String}, name: {type: String}, registered: Boolean }); |
Once you press Send on postman, the attendee should be in. Check the database:
> db.funEvents.find()
result:
{ “_id” : ObjectId(“5a2f3f9b8f4a4a4367dbf59e”),
“Event_Title” : “Super Badminton”,
“Event_Description” : “Play some badminton with fellow friends”,
“Author” : “Ricky T”,
“attendees” : [ { “phone” : “135103483252”, “name” : “Hannah Hong”, “registered” : false, “_id” : ObjectId(“5a2f405a8f4a4a4367dbf59f”) } ],
“Created_Date” : ISODate(“2017-12-12T02:31:55.180Z”),
“Event_Location” : null,
“Event_Date” : ISODate(“2017-12-12T02:31:55.180Z”), “__v” : 1 }
You will see that the attendees array now has the user Hannah Hong.
You can add as many users as you like as this is 1 to n. One event, many users.
Adding the location (1 to 1)
Adding the location to our event involves hitting the url at /events/:eventId
with a PUT verb:
eventListRoutes.js
1 2 3 4 |
app.route('/events/:eventId') .get(eventList.read_event) .put(eventList.update_event) .delete(eventList.delete_event); |
We put the event id at the end of the url like so: http://localhost/events/5a2f3f9b8f4a4a4367dbf59e
web verb: PUT
url: http://localhost/events/5a2f3f9b8f4a4a4367dbf59e
We add the information for the location via the body through
body => x-www-form-urlencoded:
address:132 Children’s park, hai yue, Shekou
city:Shenzhen
province: Guangdong
zip: 2847384
hit the “Send” button.
Finally, check your database:
> db.funEvents.find()
result:
{ “_id” : ObjectId(“5a2f3f9b8f4a4a4367dbf59e”),
“Event_Title” : “Super Badminton”,
“Event_Description” : “Play some badminton with fellow friends”,
“Author” : “Ricky T”,
“attendees” : [ { “phone” : “13510083852”, “name” : “Hannah Hong”, “registered” : false, “_id” : ObjectId(“5a2f405a8f4a4a4367dbf59f”) } ],
“Created_Date” : ISODate(“2017-12-12T02:31:55.180Z”),
“Event_Location” : { “_id” : ObjectId(“5a2f4195a713254374cbceee”), “zip” : “2847384”, “province” : “Guangdong”, “city” : “Shenzhen”, “address” : “132 Children’s park, hai yue, Shekou” },
“Event_Date” : ISODate(“2017-12-12T02:31:55.180Z”), “__v” : 1 }
Further References
Installing Mongoose
npm install mongoose –-save
Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.
/model/person.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// grab the things we need var mongoose = require('mongoose'); var Schema = mongoose.Schema; // create a schema var userSchema = new Schema({ name: String, username: { type: String, required: true, unique: true }, password: { type: String, required: true }, admin: Boolean, location: String, meta: { age: Number, website: String }, created_at: Date, updated_at: Date }, { collection: 'person'}); //the collection means the custom name of the collection you want to appear in your mongo database. Hence you would do something like db.person.find() to see all entries of your 'person' collection. // custom method to add string to end of name // you can create more important methods like name validations or formatting // you can also do queries and find similar users userSchema.methods.dudify = function() { // add some stuff to the users name this.name = this.name + '-dude'; return this.name; }; // the schema is useless so far // we need to create a model using it var Person = mongoose.model('person', userSchema); // make this available to our users in our Node applications module.exports = Person; |
/app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
var express = require('express'); var mongoose = require('mongoose'); var app = express(); var port = 3000; //Lets connect to our database using the DB server URL. mongoose.connect('mongodb://localhost/PersonDatabase'); var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function (callback) { // yay! console.log('mongoose db connected'); }); // if our user.js file is at app/models/person.js var Person = require('./models/person'); //enter person data app.get('/person', function(req, res){ var paramUN = req.query.username; console.log('username param is: ' + paramUN); if(paramUN !== undefined) { // create a new user called chris var somePerson = new Person({ name: 'Ricky', username: paramUN, password: 'compaq', admin: true }); // call the custom method. this will just add -dude to his name // user will now be Ricky-dude somePerson.dudify(function(err, name) { if (err) throw err; console.log('Your new name is ' + name); }); // call the built-in save method to save to the database somePerson.save(function(err) { try { if (err) throw err; //throw error } catch(err){ res.send("Sorry, person with username " + paramUN + ", already exists. please try another"); return; } console.log('Person saved successfully!'); res.send("Person saved successfully!"); }); } else { console.log('paramUN is NOT valid.'); res.send("Person NOT saved....param is not valid"); } }); app.listen(port, function() { console.log('7:26pm running on port ' + port); }); |
Find all People
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//find all people app.get('/admin/findall', function(req, res){ Person.find({}, function(err, people){ try { if(err) throw err; console.log(people); res.type('application/json'); res.send(people); } catch(err) { res.send(err); return; } }); }); |
Find one person
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//find one person app.get('/admin/find', function(req, res){ var paramUN = req.query.username; console.log('username param is: ' + paramUN); Person.find({ username: paramUN }, function(err, person) { try { if (err) throw err; res.type('application/json'); res.send(person); } catch(err){ res.send("User not found, " + err); return; } }); }); |
Removing Users
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
app.get('/admin/remove', function(req, res){ var unParam = req.query.username; // get the user starlord55 Person.find({ username: unParam }, function(err, person) { if (err) throw err; if(person!==undefined){ console.log('person found!' + person); // delete person Person.remove({username: unParam}, function(err) { res.send('User successfully deleted!'); }); } }); }); |