CS651 | Web Systems
  • outline
  • projects
  • syllabus
  • links

Connecting to MongDB Atlas database from NodeJS (simple run directly the nodeJS file --not invoked via CGI call)

 

 

STEP 1: setup your MongoDB Atlas database...(see other documents for help for this) & get connection information.

 

 

STEP 1.1: I have a database called shoppingsite with a collection call customers that I am going to access. Currently I have only 2 documents in it

 

STEP 1.2: Basically you follow the directions the MongoDB Atlas console gives you when you specify you want to connect from NodeJS code in order to get the URI for connection to use in your program.

 

STEP 2) You will need to install the mongodb module in your project (step 2 below) by running in the terminal of your WebStorm NodeJS+Express project that you must create:

npm install mongodb

 

 

STEP 3) In your NodeJS+Express project add at the top level of the project a file called mongoDBConnectTest.js the following code    

 

Here is the directory structure of my NodeJS + Express project with the mongoDBConnectionTest.js file at the top

 

 

Here is the code ----Read the comments to understand what it does.

const { MongoClient, ServerApiVersion } = require('mongodb');  //require model and get the MongoClient class
//STEP A: you will replace the following URI with YOUR connection string from MongoDB Atlas (go to the web console to find this const uri = "mongodb+srv://YOURLogin:YOURPassword@cluster0.WHATEVER.mongodb.net/?retryWrites=true&w=majority";

//STEP B: Create a MongoClient with a MongoClientOptions object to set the Stable API version
const client = new MongoClient(uri, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
}
}); //STEP C: THIS IS the main asynchrounous function that will run. It need to be asynchrounous // as you do not know how long it will take to run.
async function run() {
try { //there can be exceptions with connections and you need to handle them. I.E. the database server down

// STEP D: Connect the client to the server (optional starting in v4.7)
await client.connect(); //note that await is needed when you need the system to wait for it to finish
// Send a ping to confirm a successful connection
await client.db("admin").command({ ping: 1 }); //another command here that you must do await
console.log("Pinged your deployment. You successfully connected to MongoDB!");

// I have a database called shoppingsite and in it a collections called customers I will access.
var db0 = client.db("shoppingsite");
console.log("got shopping site");
console.log("db0" + db0.toString());
var collection = db0.collection("customers");
console.log("collection is "+ collection.collectionName);
console.log(" # documents in it " + await collection.countDocuments()); // STEP E: Get the first document using findOne (you can pass a query to findOne)
//see documentation for findOne https://www.w3schools.com/nodejs/nodejs_mongodb_find.asp
var results = await collection.findOne({});
console.log('grabbed 1st customers');
console.log(" entire 1st document" );
console.log(results);

// STEP F: Get "ALL" of the documents in the collection
//now grab ALL the documents in the collection
//see documentation for find which returns a curson https://www.w3schools.com/nodejs/nodejs_mongodb_query.asp
//the cursor will only hold a maximum of batch size elements at any given time if batch size is specified
// otherwise it will hold all of the documents up to what the memory will allow.
const cursor = collection.find({});
console.log("ALL Documents");
for await (const doc of cursor) {
console.log(doc);
}
// STEP G: Cycle through the Cursor using forEach command
//now using the cursor grab each one of the documents. Note cursor.rewind() makes sure
// you are at the start of the cursor documents
console.log("USING Cursor");
await cursor.rewind();
// Execute forEach command, triggers for each document
// see https://www.mongodb.com/docs/manual/reference/method/cursor.forEach/
await cursor.forEach( function( myDoc ) {
console.log(myDoc)
} );


// STEP H: Cycle through the toArray Array results using for loop
//here I am returning an array rather than a cursor
//AGAIN it will only retrieve as many documents as can fit in memory.
var arrayValues = await collection.find({}).toArray();
console.log("ALL Document using Array")
for(i=0; i<arrayValues.length; i++)
console.log(arrayValues[i]);
//for()
//console.log(arrayValues);





// STEP I: Working on INSERTION and UPDATE
//grab the songs collection
var songsCollection = db0.collection('songs');
// Create seed data -- it is in JSON format
var seedData = [
{
decade: '1970s',
artist: 'Debby Boone',
song: 'You Light Up My Life',
weeksAtOne: 10
},
{
decade: '1980s',
artist: 'Olivia Newton-John',
song: 'Physical',
weeksAtOne: 10
},
{
decade: '1990s',
artist: 'Mariah Carey',
song: 'One Sweet Day',
weeksAtOne: 16
}
];



//INSERT: insert the songs document into the collection, and follow this by an update
// Note that the insert method can take either an array or a dict.
// will use insertMany -https://www.mongodb.com/docs/current/tutorial/insert-documents/#insert-multiple-documents
// and pass our array of JSON objects in seedData
//NOTE you can also insert just one document at a time too.
// with insertOne -https://www.mongodb.com/docs/current/tutorial/insert-documents/
// also see https://www.mongodb.com/docs/v6.2/reference/method/db.collection.insertOne/
console.log("Insert Songs into songs collection");
await songsCollection.insertMany(seedData);

console.log("Insert a single song into songs collection");
await songsCollection.insertOne({"decade": "2023s", "artist": "Billie Eilish", "song": "What Was I Made For?","weeksAtOne": 10});


// STEP J: UPDATE: update documents
// you can updateOne or updateMany
// see https://www.mongodb.com/docs/current/tutorial/update-documents/
// Also see https://www.mongodb.com/docs/manual/reference/operator/update/
// to read about the $set update operator and other update operators like rename, etc
console.log("UPDATING song 'One Sweet Day' to change the artist");

await songsCollection.updateMany(
{ song: 'One Sweet Day' },
{ $set: { artist: 'Mariah Carey ft. Boyz II Men' } });

/* Note here is an example where you are changing multiple fields of the document
await db.collection('inventory').updateOne(
{ item: 'paper' },
{
$set: { 'size.uom': 'cm', status: 'P' },
$currentDate: { lastModified: true }
}
);
*/




} finally {
// Ensures that the client will close when you finish/error
await client.close();
}
}
// STEP K: NOW RUN the above defined asynchrounous run function
run().catch(console.dir);

 

 

Run this FILE (not the entire project) --- here are the results

 

"C:\Program Files\nodejs\node.exe" C:\Users\lynne\WebstormProjects\ReadFormDataSaveMongoDB\mongoDBConnectTest.js
Pinged your deployment. You successfully connected to MongoDB!
got shopping site
db0[object Object]
collection is customers
# documents in it 2
grabbed 1st customers
entire 1st document
{
_id: new ObjectId("658e211f7f246e68103ba73e"),
firstname: 'Jane',
lastname: 'Doe',
email: 'jane.doe@gmail.com'
}
ALL Documents
{
_id: new ObjectId("658e211f7f246e68103ba73e"),
firstname: 'Jane',
lastname: 'Doe',
email: 'jane.doe@gmail.com'
}
{
_id: new ObjectId("658e3b957f246e68103ba748"),
firstname: 'Jack',
lastname: 'Smith',
email: 'jsmith@horizon.csueastbay.edu'
}
USING Cursor
{
_id: new ObjectId("658e211f7f246e68103ba73e"),
firstname: 'Jane',
lastname: 'Doe',
email: 'jane.doe@gmail.com'
}
{
_id: new ObjectId("658e3b957f246e68103ba748"),
firstname: 'Jack',
lastname: 'Smith',
email: 'jsmith@horizon.csueastbay.edu'
}
ALL Document using Array
{
_id: new ObjectId("658e211f7f246e68103ba73e"),
firstname: 'Jane',
lastname: 'Doe',
email: 'jane.doe@gmail.com'
}
{
_id: new ObjectId("658e3b957f246e68103ba748"),
firstname: 'Jack',
lastname: 'Smith',
email: 'jsmith@horizon.csueastbay.edu'
}

Insert Songs into songs collection
Insert a single song into songs collection
UPDATING song 'One Sweet Day' to change the artist

 

Process finished with exit code 0

 

 

After running the NodeJS we get some documents in the collections songs.

 

 

 

 

 

What will happen to our collection of songs if I run this NodeJS code again???

I ran the code 2 times so first time, it inserted 4 documents and the second time it inserted again 4 documents---for a total of 8 documents

So, now there is actually 4 pairs of documents where in each pair ALL of the data is the SAME except the _id field.

As the _id (unique identifier) was not specified, it is unique with each insert --if it had been specified only 4 documents would be created regardless of the number of times I ran the code.

 

 

 

 

 

 

Understanding some of the code...more

 

 

Understanding some of the code -see CRUD (create, read, update, delete) in action

mongodb.MongoClient.connect(uri, function(err, db) connect to specified uri and execute function upon connection
var seedData = [
 {
 decade: '1970s',
 artist: 'Debby Boone',
 song: 'You Light Up My Life',
 weeksAtOne: 10
 },
 {
 decade: '1980s',
 artist: 'Olivia Newton-John',
 song: 'Physical',
 weeksAtOne: 10
 },
 {
 decade: '1990s',
 artist: 'Mariah Carey',
 song: 'One Sweet Day',
 weeksAtOne: 16
 }
 ];

This is the JSON object representing 3 entries in our songs collection we want to enter.

 

 

NOTE: we have 4 idices (like columns) in our songs collection (like a databasetable) and they are:

  • decade
  • artist
  • song
  • weeksAtOne

 

songs.insert(seedData, function(err, result)

try to insert new entries into the songs collection first creating the collection if it does not already exist

the entries are represented by the json object "seedData"

execute the function upon callback (being done)

songs.update(
{ song: 'One Sweet Day' },
{ $set: { artist: 'Mariah Carey ft. Boyz II Men' } },
function (err, result)

update entry with song='One Sweet Day' to change the artist to ='Mariah Carey ft. Boyz II Men'

when done call the call back funciton specified

songs.find({ weeksAtOne : { $gte: 10 } }).sort({ decade: 1 }).toArray(function (err, docs) {

this is like a select (read) statment where weeksAtOne>10 and sorting by decade in asscending order (that is the :1) and then get results as an array that is passed to the call back function
function (err, docs) {
  
if(err) throw err;
 docs.forEach(function (doc) {
   console.log('In the ' + doc['decade'] + ', ' + doc['song'] + ' by ' +
doc['artist'] + ' topped the charts for ' + doc['weeksAtOne'] +
' straight weeks.'); });

This cycles through the docs[] array representing the retrieved entries from the songs collection.

 

Note you access items by indexing the array docs[] with a column value called an index in mongoDB collection

 

 

DESIGN: Direct Access from user Application or Go through an API ??????

 

while more work creating an API initially, it means that you DONT DUPLICATE the work from your different interfaces like a web (Angular), different server application (e.g. NodeJS) or a mobile App (e.g. iOS).

 

What does it mean to create an API --- you create a series of spearate applications (like in NodeJS with Express) that serve up results of desired CRUD operations on your Database that are accessed via WEB URLs ---example

 

cs651:web systems

  • home
  • outline
  • projects
  • syllabus
  • links