From b07915dbf070873614eb10088bc3798e030faf27 Mon Sep 17 00:00:00 2001 From: Lauren Schaefer Date: Thu, 18 Feb 2021 11:44:04 -0500 Subject: [PATCH 1/7] Update pipe link --- changeStreams.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changeStreams.js b/changeStreams.js index 277c897..37a5b7a 100644 --- a/changeStreams.js +++ b/changeStreams.js @@ -137,7 +137,7 @@ async function monitorListingsUsingStreamAPI(client, timeInMs = 60000, pipeline // See https://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#watch for the watch() docs const changeStream = collection.watch(pipeline); - // See https://mongodb.github.io/node-mongodb-native/3.6/api/ChangeStream.html#pipe for the pipe() docs + // See https://mongodb.github.io/node-mongodb-native/3.6/api/ChangeStream.html#stream for the stream() docs changeStream.stream().pipe( new stream.Writable({ objectMode: true, From 67b6c67807ef1d852ce7292d6e19afab9cec720d Mon Sep 17 00:00:00 2001 From: va6un Date: Mon, 10 May 2021 23:12:00 +0530 Subject: [PATCH 2/7] Warning workaround. Use unused variable --- read.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/read.js b/read.js index 53b6568..91fc423 100644 --- a/read.js +++ b/read.js @@ -10,6 +10,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); @@ -89,14 +92,14 @@ async function findListingsWithMinimumBedroomsBathroomsAndMostRecentReviews(clie if (results.length > 0) { console.log(`Found listing(s) with at least ${minimumNumberOfBedrooms} bedrooms and ${minimumNumberOfBathrooms} bathrooms:`); results.forEach((result, i) => { - date = new Date(result.last_review).toDateString(); + const date = new Date(result.last_review).toDateString(); console.log(); console.log(`${i + 1}. name: ${result.name}`); console.log(` _id: ${result._id}`); console.log(` bedrooms: ${result.bedrooms}`); console.log(` bathrooms: ${result.bathrooms}`); - console.log(` most recent review date: ${new Date(result.last_review).toDateString()}`); + console.log(` most recent review date: ${date}`); }); } else { console.log(`No listings found with at least ${minimumNumberOfBedrooms} bedrooms and ${minimumNumberOfBathrooms} bathrooms`); From 2c209f67b4a48a5d6b15952584368188ac62648b Mon Sep 17 00:00:00 2001 From: va6un Date: Mon, 24 May 2021 11:48:10 +0530 Subject: [PATCH 3/7] Add warning workaround --- aggregation.js | 3 +++ changeStreams.js | 3 +++ changeStreamsTestData.js | 3 +++ connection.js | 3 +++ create.js | 3 +++ delete.js | 3 +++ template.js | 3 +++ transaction.js | 3 +++ update.js | 3 +++ usersCollection.js | 3 +++ 10 files changed, 30 insertions(+) diff --git a/aggregation.js b/aggregation.js index 32baad8..eaa47b7 100644 --- a/aggregation.js +++ b/aggregation.js @@ -10,6 +10,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/changeStreams.js b/changeStreams.js index 37a5b7a..2902b10 100644 --- a/changeStreams.js +++ b/changeStreams.js @@ -11,6 +11,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/changeStreamsTestData.js b/changeStreamsTestData.js index ecc774d..7867494 100644 --- a/changeStreamsTestData.js +++ b/changeStreamsTestData.js @@ -14,6 +14,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/connection.js b/connection.js index f504282..85a9e12 100644 --- a/connection.js +++ b/connection.js @@ -10,6 +10,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/create.js b/create.js index 6ad1fc8..d1d302c 100644 --- a/create.js +++ b/create.js @@ -10,6 +10,9 @@ async function main(){ /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/delete.js b/delete.js index fca8743..32b9646 100644 --- a/delete.js +++ b/delete.js @@ -10,6 +10,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/template.js b/template.js index 39ab3e8..2785d10 100644 --- a/template.js +++ b/template.js @@ -10,6 +10,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/transaction.js b/transaction.js index 754e11e..33ff107 100644 --- a/transaction.js +++ b/transaction.js @@ -14,6 +14,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/update.js b/update.js index b107c55..e82e894 100644 --- a/update.js +++ b/update.js @@ -10,6 +10,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); diff --git a/usersCollection.js b/usersCollection.js index 4f6250c..ba492eb 100644 --- a/usersCollection.js +++ b/usersCollection.js @@ -20,6 +20,9 @@ async function main() { /** * The Mongo Client you will use to interact with your database * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + * In case: '[MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated...' + * pass option { useUnifiedTopology: true } to the MongoClient constructor. + * const client = new MongoClient(uri, {useUnifiedTopology: true}) */ const client = new MongoClient(uri); From c745999af68789db57a0d1106213241aa755a0d1 Mon Sep 17 00:00:00 2001 From: Lauren Schaefer Date: Fri, 17 Sep 2021 10:39:37 -0400 Subject: [PATCH 4/7] Add Transactions Banking Example --- transaction-bankingexample.js | 128 ++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 transaction-bankingexample.js diff --git a/transaction-bankingexample.js b/transaction-bankingexample.js new file mode 100644 index 0000000..62261d4 --- /dev/null +++ b/transaction-bankingexample.js @@ -0,0 +1,128 @@ +const { MongoClient } = require('mongodb'); + +// In MongoDB 4.2 and earlier, CRUD operations in transactions must be on existing collections +// See https://docs.mongodb.com/manual/core/transactions/#transactions-api for more information + +// Before running this script... +// 1. Create a database named 'banking' +// 2. Create a collection named 'accounts' in the database +// 3. Create two documents in the 'accounts' collection: +// {"_id":"account1", "balance":500} +// {"_id":"account2", "balance":0} +// 4: Optional: add schema validation to ensure an account balance cannot drop below 0. +// See https://docs.mongodb.com/manual/core/schema-validation/ for details on how to +// enable schema validation. Configuring schema validation in MongoDB Compass is an +// easy way to add schema validation to an existing database: https://docs.mongodb.com/compass/current/validation/ +// +// { +// $jsonSchema: { +// properties: { +// balance: { +// minimum: 0, +// description: 'account balance cannot be negative' +// } +// } +// } +// } + +async function main() { + /** + * Connection URI. Update , , and to reflect your cluster. + * See https://docs.mongodb.com/drivers/node/ for more details + */ + const uri = "mongodb+srv://:@/sample_airbnb?retryWrites=true&w=majority"; + + /** + * The Mongo Client you will use to interact with your database + * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + */ + const client = new MongoClient(uri); + + try { + // Connect to the MongoDB cluster + await client.connect(); + + // Transfer $100 from "account1" to "account2" + await transferMoney(client, "account1", "account2", 100); + + } finally { + // Close the connection to the MongoDB cluster + await client.close(); + } +} + +main().catch(console.error); + +/** + * Transfer money from one bank account to another using + * @param {MongoClient} client A MongoClient that is connected to a cluster with the banking database + * @param {String} account1 The _id of the account where money should be subtracted + * @param {String} account2 The _id of the account where money should be added + * @param {Number} amount The amount of money to be transferred + */ +async function transferMoney(client, account1, account2, amount) { + + /** + * The accounts collection in the banking database + */ + const accountsCollection = client.db("banking").collection("accounts"); + + // Step 1: Start a Client Session + // See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html#startSession for the startSession() docs + const session = client.startSession(); + + // Step 2: Optional. Define options for the transaction + const transactionOptions = { + readPreference: 'primary', + readConcern: { level: 'local' }, + writeConcern: { w: 'majority' } + }; + + try { + // Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error) + // Note: The callback for withTransaction MUST be async and/or return a Promise. + // See https://mongodb.github.io/node-mongodb-native/3.6/api/ClientSession.html#withTransaction for the withTransaction() docs + const transactionResults = await session.withTransaction(async () => { + + // Important:: You must pass the session to each of the operations + + // Remove the money from the first account + const subtractMoneyResults = await accountsCollection.updateOne( + { _id: account1 }, + { $inc: { balance: amount * -1 } }, + { session }); + console.log(`${subtractMoneyResults.matchedCount} document(s) found in the accounts collection with _id ${account1}.`); + console.log(`${subtractMoneyResults.modifiedCount} document(s) was/were updated to remove the money.`); + if (subtractMoneyResults.modifiedCount !== 1) { + await session.abortTransaction(); + return; + } + + // Add the money to the second account + const addMoneyResults = await accountsCollection.updateOne( + { _id: account2 }, + { $inc: { balance: amount } }, + { session }); + console.log(`${addMoneyResults.matchedCount} document(s) found in the accounts collection with _id ${account2}.`); + console.log(`${addMoneyResults.modifiedCount} document(s) was/were updated to add the money.`); + if (addMoneyResults.modifiedCount !== 1) { + await session.abortTransaction(); + return; + } + + }, transactionOptions); + + if (transactionResults) { + console.log("The money was successfully transferred."); + } else { + console.log("The money was not transferred. The transaction was intentionally aborted."); + } + } catch (e) { + console.log("The money was not transferred. The transaction was aborted due to an unexpected error: " + e); + } finally { + // Step 4: End the session + await session.endSession(); + } + +} + From 6cc0b98edc775310e9d967c36fcd4291e693894d Mon Sep 17 00:00:00 2001 From: Lauren Schaefer Date: Fri, 17 Sep 2021 11:01:36 -0400 Subject: [PATCH 5/7] Fix connection string and wording --- transaction-bankingexample.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/transaction-bankingexample.js b/transaction-bankingexample.js index 62261d4..9ed5479 100644 --- a/transaction-bankingexample.js +++ b/transaction-bankingexample.js @@ -30,7 +30,7 @@ async function main() { * Connection URI. Update , , and to reflect your cluster. * See https://docs.mongodb.com/drivers/node/ for more details */ - const uri = "mongodb+srv://:@/sample_airbnb?retryWrites=true&w=majority"; + const uri = "mongodb+srv://:@/banking?retryWrites=true&w=majority"; /** * The Mongo Client you will use to interact with your database @@ -113,7 +113,7 @@ async function transferMoney(client, account1, account2, amount) { }, transactionOptions); if (transactionResults) { - console.log("The money was successfully transferred."); + console.log("The money was successfully transferred. Database operations from the transaction are now visible outside the transaction."); } else { console.log("The money was not transferred. The transaction was intentionally aborted."); } From 40d6dd7452332466ba93b78d82ad1534d1be6180 Mon Sep 17 00:00:00 2001 From: Lauren Schaefer Date: Mon, 4 Oct 2021 08:46:00 -0400 Subject: [PATCH 6/7] Add transactions inventory example --- transaction-inventoryexample.js | 127 ++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 transaction-inventoryexample.js diff --git a/transaction-inventoryexample.js b/transaction-inventoryexample.js new file mode 100644 index 0000000..42505b1 --- /dev/null +++ b/transaction-inventoryexample.js @@ -0,0 +1,127 @@ +const { MongoClient } = require('mongodb'); + +// In MongoDB 4.2 and earlier, CRUD operations in transactions must be on existing collections +// See https://docs.mongodb.com/manual/core/transactions/#transactions-api for more information + +// Before running this script... +// 1. Create a database named 'book-store' +// 2. Create a collection named 'orders' in the database +// 3. Create a collection named 'inventory' in the database +// 3. Create a document in the 'inventory' collection: +// { "_id": "parks-rec-book", "name": "The Ultimate Parks and Rec Book for the Ultimate Fans", "numberInStock": 5 } +// 4: Optional: Add schema validation to the 'inventory' collection to ensure the number of items in stock cannot drop below 0. +// See https://docs.mongodb.com/manual/core/schema-validation/ for details on how to +// enable schema validation. Configuring schema validation in MongoDB Compass is an +// easy way to add schema validation to an existing database: https://docs.mongodb.com/compass/current/validation/ +// +// { +// $jsonSchema: { +// properties: { +// numberInStock: { +// minimum: 0, +// description: 'numberInStock cannot be negative' +// } +// } +// } +// } + +async function main() { + /** + * Connection URI. Update , , and to reflect your cluster. + * See https://docs.mongodb.com/drivers/node/ for more details + */ + const uri = "mongodb+srv://:@/book-store?retryWrites=true&w=majority"; + + /** + * The Mongo Client you will use to interact with your database + * See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details + */ + const client = new MongoClient(uri); + + try { + // Connect to the MongoDB cluster + await client.connect(); + + // User1 purchases 1 copy of parks-rec-book + await purchaseBook(client, "User1", "parks-rec-book", 1, "paid"); + + } finally { + // Close the connection to the MongoDB cluster + await client.close(); + } +} + +main().catch(console.error); + +/** + * Purchase a book + * @param {MongoClient} client A MongoClient that is connected to a cluster with the book-store database + * @param {String} userId The _id of the user who is purchasing the book + * @param {String} bookId The _id of the book being purchased + * @param {Number} quantity The number of copies being purchased + * @param {String} status The order status + */ +async function purchaseBook(client, userId, bookId, quantity, status) { + + /** + * The orders collection in the book-store database + */ + const ordersCollection = client.db("book-store").collection("orders"); + + /** + * The inventory collection in the book-store database + */ + const inventoryCollection = client.db("book-store").collection("inventory"); + + // Step 1: Start a Client Session + // See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html#startSession for the startSession() docs + const session = client.startSession(); + + // Step 2: Optional. Define options for the transaction + const transactionOptions = { + readPreference: 'primary', + readConcern: { level: 'local' }, + writeConcern: { w: 'majority' } + }; + + try { + // Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error) + // Note: The callback for withTransaction MUST be async and/or return a Promise. + // See https://mongodb.github.io/node-mongodb-native/3.6/api/ClientSession.html#withTransaction for the withTransaction() docs + const transactionResults = await session.withTransaction(async () => { + + // Important:: You must pass the session to each of the operations + + // Update the inventory to reflect the book has been sold + const updateInventoryResults = await inventoryCollection.updateOne( + { _id: bookId }, + { $inc: { numberInStock: quantity * -1 } }, + { session }); + console.log(`${updateInventoryResults.matchedCount} document(s) found in the inventory collection with _id ${bookId}.`); + console.log(`${updateInventoryResults.modifiedCount} document(s) was/were updated.`); + if (updateInventoryResults.modifiedCount !== 1) { + await session.abortTransaction(); + return; + } + + // Record the order in the orders collection + const insertOrderResults = await ordersCollection.insertOne( + { "userId": userId , bookId: bookId, quantity: quantity, status: status }, + { session }); + console.log(`New order recorded with the following id: ${insertOrderResults.insertedId}`); + + }, transactionOptions); + + if (transactionResults) { + console.log("The order was successfully processed. Database operations from the transaction are now visible outside the transaction."); + } else { + console.log("The order was not successful. The transaction was intentionally aborted."); + } + } catch (e) { + console.log("The order was not successful. The transaction was aborted due to an unexpected error: " + e); + } finally { + // Step 4: End the session + await session.endSession(); + } + +} From 584a1a5371e064df648fedf9a71ccbc33b75afcf Mon Sep 17 00:00:00 2001 From: Stanimira Vlaeva Date: Wed, 13 Oct 2021 14:59:36 +0300 Subject: [PATCH 7/7] chore: apply license to MongoDB Inc. --- LICENSE | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/LICENSE b/LICENSE index 261eeb9..6fad4e7 100644 --- a/LICENSE +++ b/LICENSE @@ -175,18 +175,7 @@ END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] + Copyright 2021 MongoDB Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +187,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. + limitations under the License. \ No newline at end of file