From 639b47ac2e15109affd0d56ad699b5a50473c013 Mon Sep 17 00:00:00 2001 From: Stephanie Aurelio Date: Thu, 15 May 2025 11:26:45 -0700 Subject: [PATCH 01/20] add get started guide and code snippets --- .../mongoose-blogSchema-validate.js | 47 ++ .../integrations/mongoose-blogSchema.js | 21 + .../mongoose-get-started-blogSchema.js | 45 ++ .../mongoose-get-started-multiple-schemas.js | 36 + .../integrations/mongoose-model-example.js | 1 + .../integrations/mongoose-schema-example.js | 21 + .../integrations/mongoose-userSchema.js | 18 + source/index.txt | 1 + source/integrations.txt | 24 + source/integrations/mongoose-get-started.txt | 636 ++++++++++++++++++ 10 files changed, 850 insertions(+) create mode 100644 source/includes/integrations/mongoose-blogSchema-validate.js create mode 100644 source/includes/integrations/mongoose-blogSchema.js create mode 100644 source/includes/integrations/mongoose-get-started-blogSchema.js create mode 100644 source/includes/integrations/mongoose-get-started-multiple-schemas.js create mode 100644 source/includes/integrations/mongoose-model-example.js create mode 100644 source/includes/integrations/mongoose-schema-example.js create mode 100644 source/includes/integrations/mongoose-userSchema.js create mode 100644 source/integrations.txt create mode 100644 source/integrations/mongoose-get-started.txt diff --git a/source/includes/integrations/mongoose-blogSchema-validate.js b/source/includes/integrations/mongoose-blogSchema-validate.js new file mode 100644 index 000000000..8aa5e6228 --- /dev/null +++ b/source/includes/integrations/mongoose-blogSchema-validate.js @@ -0,0 +1,47 @@ +import mongoose from 'mongoose'; +const { Schema, SchemaTypes, model } = mongoose; + +// start-blogSchema +const blogSchema = new Schema({ + title: { + type: String, + required: true, + }, + slug: { + type: String, + required: true, + lowercase: true, + }, + published: { + type: Boolean, + default: false, + }, + author: { + type: String, + required: true, + }, + content: String, + tags: [String], + createdAt: { + type: Date, + default: () => Date.now(), + immutable: true, + }, + updated: Date, + comments: [{ + user: String, + content: String, + votes: Number + }] +}); +// end-blogSchema + +// start-blogSchema-middleware +blogSchema.pre('save', function(next) { + this.updated = Date.now(); + next(); +}); +// end-blogSchema-middleware + +const Blog = model('Blog', blogSchema); +export default Blog; \ No newline at end of file diff --git a/source/includes/integrations/mongoose-blogSchema.js b/source/includes/integrations/mongoose-blogSchema.js new file mode 100644 index 000000000..e19cf23fc --- /dev/null +++ b/source/includes/integrations/mongoose-blogSchema.js @@ -0,0 +1,21 @@ +import mongoose from 'mongoose'; +const { Schema, model } = mongoose; + +const blogSchema = new Schema({ + title: String, + slug: String, + published: Boolean, + author: String, + content: String, + tags: [String], + createdAt: Date, + updated: Date, + comments: [{ + user: String, + content: String, + votes: Number + }] +}); + +const Blog = model('Blog', blogSchema); +export default Blog; diff --git a/source/includes/integrations/mongoose-get-started-blogSchema.js b/source/includes/integrations/mongoose-get-started-blogSchema.js new file mode 100644 index 000000000..8aa0423b7 --- /dev/null +++ b/source/includes/integrations/mongoose-get-started-blogSchema.js @@ -0,0 +1,45 @@ +import mongoose from 'mongoose'; +// start-blogSchema-import +import Blog from './model/Blog.js'; +// end-blogSchema-import + +mongoose.connect(""); + +// start-insert +// Creates a new blog post and inserts it into database +const article = await Blog.create({ + title: 'Awesome Post!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: ['featured', 'announcement'], +}); + +console.log('Created article:', article); +// end-insert + +// start-update +article.title = "The Most Awesomest Post!!"; +await article.save(); +console.log('Updated Article:', article); +// end-update + +// start-find-by-id +const articleFound = await Blog.findById("").exec(); +console.log('Found Article by ID:', articleFound); +// end-find-by-id + +// start-project-fields +const articleProject = await Blog.findById("", "title slug content").exec(); +console.log('Projected Article:', articleProject); +// end-project-fields + +// start-delete-one +const blogOne = await Blog.deleteOne({ slug: "awesome-post" }); +console.log('Deleted One Blog:', blogOne); +// end-delete-one + +// start-delete-many +const blogMany = await Blog.deleteMany({ slug: "awesome-post" }); +console.log('Deleted Many Blogs:', blogMany); +// end-delete-many \ No newline at end of file diff --git a/source/includes/integrations/mongoose-get-started-multiple-schemas.js b/source/includes/integrations/mongoose-get-started-multiple-schemas.js new file mode 100644 index 000000000..e2d99d9f5 --- /dev/null +++ b/source/includes/integrations/mongoose-get-started-multiple-schemas.js @@ -0,0 +1,36 @@ +import mongoose from 'mongoose'; +import Blog from './model/Blog.js'; +// start-user-import +import User from './model/User.js'; +// end-user-import + +mongoose.connect(""); + +// start-article-with-author +const user = await User.create({ + name: 'Jess Garica', + email: 'jgarcia@email.com', +}); + +const articleAuthor = await Blog.create({ + title: 'Awesome Post!', + slug: 'Awesome-Post', + author: user._id, + content: 'This is the best post ever', + tags: ['featured', 'announcement'], +}); + +console.log('Article with Author:', articleAuthor); +// end-article-with-author + +// start-populate-author +const articlePopulate = await Blog.findOne({ title: "Awesome Post!" }).populate("author"); +console.log('Article Populated:', articlePopulate); +// end-populate-author + +// start-middleware-update +const articleUpdated = await Blog.findById("68262cac638b7ec7ed0a086b").exec(); +articleUpdated.title = "Updated Title"; +await articleUpdated.save(); +console.log('Article Updated:', articleUpdated); +// end-middleware-update \ No newline at end of file diff --git a/source/includes/integrations/mongoose-model-example.js b/source/includes/integrations/mongoose-model-example.js new file mode 100644 index 000000000..e5e916e99 --- /dev/null +++ b/source/includes/integrations/mongoose-model-example.js @@ -0,0 +1 @@ +const Blog = mongoose.model('Blog', blog); \ No newline at end of file diff --git a/source/includes/integrations/mongoose-schema-example.js b/source/includes/integrations/mongoose-schema-example.js new file mode 100644 index 000000000..9b936d1b0 --- /dev/null +++ b/source/includes/integrations/mongoose-schema-example.js @@ -0,0 +1,21 @@ +import mongoose from 'mongoose'; +const { Schema, model } = mongoose; +// start-schema-example +const blog = new Schema({ + title: String, + slug: String, + published: Boolean, + author: String, + content: String, + tags: [String], + createdAt: Date, + updated: Date, + comments: [{ + user: String, + content: String, + votes: Number + }] +}); +// end-schema-example +const Blog = model('Blog', blogSchema); +export default Blog; \ No newline at end of file diff --git a/source/includes/integrations/mongoose-userSchema.js b/source/includes/integrations/mongoose-userSchema.js new file mode 100644 index 000000000..d53a4bd6e --- /dev/null +++ b/source/includes/integrations/mongoose-userSchema.js @@ -0,0 +1,18 @@ +import mongoose from 'mongoose'; +const {Schema, model} = mongoose; + +const userSchema = new Schema({ + name: { + type: String, + required: true, + }, + email: { + type: String, + minLength: 10, + required: true, + lowercase: true + }, +}); + +const User = model('User', userSchema); +export default User; diff --git a/source/index.txt b/source/index.txt index 391860dd2..e366eaf5f 100644 --- a/source/index.txt +++ b/source/index.txt @@ -29,6 +29,7 @@ MongoDB Node Driver Atlas Vector Search Monitoring and Logging Security + Third-Party Integrations Reference TypeScript API Documentation <{+api+}> diff --git a/source/integrations.txt b/source/integrations.txt new file mode 100644 index 000000000..28dc60f4c --- /dev/null +++ b/source/integrations.txt @@ -0,0 +1,24 @@ +.. _node-integrations: + +================================== +Third-Party Integrations and Tools +================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: i + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + Get Started with Mongoose diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt new file mode 100644 index 000000000..14105b233 --- /dev/null +++ b/source/integrations/mongoose-get-started.txt @@ -0,0 +1,636 @@ +.. _node-mongoose-get-started: + +========================= +Get Started with Mongoose +========================= + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Learn how to create an app to connect to MongoDB and perform CRUD operations by using Mongoose. + :keywords: integrations, mongoose, crud + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Overview +-------- + +Mongoose is an Object Data Modeling (ODM) library for MongoDB. You can use +Mongoose to help with data modeling, schema enforcement, model validation, and +general data manipulation. Because MongoDB has a flexible data model that allows +you to easily alter and update databases in the future, there aren't rigid +schemas. Mongoose enforces a semi-regid schema from the beginning. When you use +Mongoose, you must define a schema and model. + +In this tutorial, you will perform the following actions: + +- Set up your environment to use Mongoose +- Connect to MongoDB +- Create a Mongoose schema and model +- Insert, update, find, and delete data +- Project document fields +- Validate your data +- Use multiple schemas and middleware + +You will also learn other useful methods to grow your experience using Mongoose with MongoDB. + +Schemas +------- + +A schema defines the structure of your collection documents. A Mongoose schema +maps directly to a MongoDB collection. + +The following example creates a new Schema named ``blog``: + +.. literalinclude:: /includes/integrations/mongoose-schema-example.js + :language: javascript + :start-after: start-schema-example + :end-before: end-schema-example + :dedent: + +When you create a schema, you must define each field and its data types. The +following types are permitted: + +- String +- Number +- Date +- Buffer +- Boolean +- Mixed +- ObjectId +- Array +- Decimal128 +- Map + +Models +------ + +Models take your schema and apply it to each document in its collection. Models +are responsible for all document interactions such as create, read, update, and +delete (CRUD) operations. + +.. tip:: + + The first argument you pass to the model is the singular form of your + collection name. Mongoose automatically changes this to the plural form, + transforms it to lowercase, and uses that for the database collection name. + +The following example shows how to declare a model named ``Blog`` that uses the +``blog`` schema: + +.. literalinclude:: /includes/integrations/mongoose-model-example.js + :language: javascript + :dedent: + +In the preceding example, ``Blog`` translates to the ``blogs`` collection in +MongoDB. + +Prerequisites +------------- + +Before you begin this tutorial, perform the following actions: + +- Set up a MongoDB Atlas account and configure a cluster that is M0 or higher. + To view instructions, see the :atlas:`Get Started with Atlas + ` guide. +- Install `Node.js `__ {+min-node-version+} or later. + +Set Up Your Environment +----------------------- + +This tutorial uses npm to install dependencies and nodemon to run the code +locally. Run the following commands in your terminal to initialize your project +and install the necessary dependencies: + +.. code-block:: bash + + mkdir mongodb-mongoose + cd mongodb-mongoose + npm init -y + npm i mongoose + npm i -D nodemon + +Open your project in your preferred code editor. This tutorial uses ES Modules +instead of CommonJS. You need to add the module type to use ES Modules. Go to +the package.json file and add the following code: + +.. code-block:: json + + ... + "scripts": { + "dev": "nodemon index.js" + }, + "type": "module", + ... + +Connect to MongoDB +------------------ + +In the root level of your project, create a file named ``index.js`` and add the +following code to the top of the file: + +.. code-block:: javascript + + import mongoose from 'mongoose'; + + mongoose.connect("") + +Replace the ```` placeholder with your MongoDB Atlas +connection string. For more information on how to find your connection string, +see the :atlas:`Connect to Your Cluster ` +tutorial in the Atlas documentation. + +Create a Schema and Model +------------------------- + +Before you start adding and updating data in MongoDB, you must create a schema +and model. + +With Mongoose, you create a schema model file for each schema that is needed. To +do this, use the folder/file structure. Create the ``model/Blog.js`` +folder/file. Open this file and add the following code: + +.. literalinclude:: /includes/integrations/mongoose-blogSchema.js + :language: javascript + :dedent: + +You now have your first model and schema set up, and you can start inserting +data in the database. + +Insert Data +----------- + +Go to ``index.js`` and add the following import statement to the top of your file: + +.. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-blogSchema-import + :end-before: end-blogSchema-import + :dedent: + +Add the following code below the line that contains your connection string: + +.. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-insert + :end-before: end-insert + :dedent: + +The preceding code uses the Mongoose ``create()`` method to instantiate the object +representing a blog article, and then saves it to the database. The returned +document logs to the console, including its ``_id``. Take note of this ``_id`` for use +in future steps. + +To run the code, use the following command in your terminal: + +.. io-code-block:: + :copyable: + + .. input:: + :language: bash + + npm run dev + + .. output:: + :language: console + :visible: false + + Created article: { + title: 'Awesome Post!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + _id: new ObjectId('...'), + comments: [], + __v: 0 + } + +.. note:: + + When you use nodemon, the code runs every time you save a file. Saving will + insert multiple articles into your database. + +Update Data +----------- + +To update data, you can directly edit the local object with Mongoose. Then, you +can use the ``save()`` method to write the update to the database. Add the +following code to update the article you inserted in the previous section: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-update + :end-before: end-update + + .. output:: + :language: console + :visible: false + + Updated Article: { + title: 'The Most Awesomest Post!!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + _id: new ObjectId('...'), + comments: [], + __v: 0 + } + +Find Data +--------- + +To update a specific document, you can use the Mongoose ``findById()`` method to get +a document by its ObjectId. + +Add following code to your ``index.js`` file to find a specific article by its +ObjectId, replacing the ```` placeholder with the ObjectId for the +document that you inserted previously: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-find-by-id + :end-before: end-find-by-id + + .. output:: + :language: console + :visible: false + + Found Article by ID: { + _id: new ObjectId('68261c9dae39e390341c367c'), + title: 'The Most Awesomest Post!!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + comments: [], + __v: 0 + } + +.. note:: + + The Mongoose ``exec()`` function is an option of the ``findById()`` method that + returns a promise. To learn more about working with promises and Mongoose, + see the `Promises guide `__ in the Mongoose documentation. + +Specify Document Fields +----------------------- + +Like with the {+driver-short+}, you can use Mongoose to project only the fields that +you need. The following code specifies to only project the ``title``, ``slug``, and +``content`` fields. + +Add the following code to your ``index.js`` file, replacing the +```` placeholder with the ObjectId for the document that you inserted +previously: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-project-fields + :end-before: end-project-fields + + .. output:: + :language: console + :visible: false + + Projected Article: { + _id: new ObjectId('...'), + title: 'The Most Awesomest Post!!', + slug: 'awesome-post', + content: 'This is the best post ever' + } + +Delete Data +----------- + +Mongoose uses the ``deleteOne()`` and ``deleteMany()`` methods to delete data from a +collection. You can specify the field of the document you want to delete and +pass that field to the method that you choose. + +Add the following code to your index.js file to delete one article from the +database: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-delete-one + :end-before: end-delete-one + + .. output:: + :language: console + :visible: false + + Deleted One Blog: { acknowledged: true, deletedCount: 1 } + +To delete multiple articles, you can add the following code: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-delete-many + :end-before: end-delete-many + + .. output:: + :language: console + :visible: false + + Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } + +Additional Methods +------------------ + +Mongoose includes several helper methods that are abstracted from regular +MongoDB methods. In this section, you can find examples of some of these +methods. You don't need to add these methods to your ``index.js`` file to proceed +with the tutorial, but they are helpful to reference. + +exists() +~~~~~~~~ + +The ``exists()`` method returns either null or the ObjectId of a document that +matches the provided query. The following is an example of matching an article +based on the ``author`` field: + +.. code-block:: javascript + + const blog = await Blog.exists({ author: 'Jess Garcia' }); + console.log(blog); + +where() +~~~~~~~ + +Mongoose has a unique style of querying data. The ``where()`` method allows you to +chain and build queries. The following is an example of performing a find +operation using ``findOne()`` and the equivalent approach using the ``where()`` method: + +.. code-block:: javascript + + const blogFind = await Blog.findOne({ author: "Jess Garcia" }); + + const blogWhere = await Blog.where("author").equals("Jess Garcia"); + console.log(blogWhere) + +You can use either method to perform find operations. You can also chain +multiple ``where()`` methods to build increasingly complex queries. + +To include projection when using the ``where()`` method, chain the ``select()`` method +after your query, as shown in the following example: + +.. code-block:: javascript + + const blog = await Blog.where("author").equals("Jess Garcia").select("title author") + console.log(blog) + + +Validate Your Data +------------------ + +If you refer to the schema, note that the articles inserted so far have not +contained the ``author``, ``dates``, or ``comments`` fields even though these fields are +included in the schema. This is because although you defined the structure of +your document, you have not defined which fields are required. Without defining +the required fields, you can omit any fields. + +To add data validation and define these requirements, update the schema in +``Blog.js`` like the following: + +.. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js + :language: javascript + :start-after: start-blogSchema + :end-before: end-blogSchema + :dedent: + +In Mongoose, when you include validation on a field, you must pass an object as +its value. + +.. tip:: + + When you use schemas with Mongoose, ``value: String`` is the same as + ``value: {type: String}``. + +You can use several validation methods with Mongoose. For example, you can set +``required`` to true on any fields that you would like to require. + +You can also validate the type and the formatting. In the preceding code, the +``slug`` field is defined as a ``string`` that is always in ``lowercase``. This +validation takes the slug input and converts it to lowercase before saving the +document to the database. + +For the ``createdAt`` date field, you can set the default by using an arrow function. +This field is also specified to be impossible to change later by setting +``immutable`` to ``true``. + +.. note:: + + Validators only run on the ``create()`` and ``save()`` methods. + +Multiple Schemas +---------------- + +Now that you have validation on your blog schema, and the author field is +``required``, you need to update ``index.js`` to include the author. To do this, +you can create a separate schema. + +In the model folder, create a new file named ``User.js``. Add the following code to +this file: + +.. literalinclude:: /includes/integrations/mongoose-userSchema.js + :language: javascript + :dedent: + +To reference blog schema, update the ``Blog.js`` file to include the following +code: + +.. code-block:: javascript + + import mongoose from 'mongoose'; + const { Schema, SchemaTypes, model } = mongoose; + + const blogSchema = new Schema({ + ... + author: { + type: SchemaTypes.ObjectId, + ref: 'User', + required: true, + }, + ..., + comments: [{ + user: { + type: SchemaTypes.ObjectId, + ref: 'User', + required: true, + }, + content: String, + votes: Number + }]; + }); + ... + + +The preceding code sets the ``author`` and ``comments.user`` to ``SchemaTypes.ObjectId`` and +adds a ``ref``, or reference, to the user model. Be sure to destructure ``SchemaTypes`` +from Mongoose at the top of the file below the import statement. + +To use the new user model in your application, go to the ``index.js`` file. Add +the following code to the top of the file to import the user model: + +.. literalinclude:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-user-import + :end-before: end-user-import + +Since you added field validation to the blog schema, the previous code to +insert, update, and delete blogs, as well as to specify fields to project, won't +pass the validation and the application will error. + +Replace the existing code with the following code to create a new user, and then +create a new article that uses this user as the author, as shown in the +following code: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-article-with-author + :end-before: end-article-with-author + + .. output:: + :language: console + :visible: false + + Article with Author: { + title: 'Awesome Post!', + slug: 'awesome-post', + published: false, + author: new ObjectId('...'), + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + _id: new ObjectId('...'), + createdAt: 2025-05-15T18:05:23.780Z, + comments: [], + __v: 0 + } + +The preceding code adds a ``users`` collection along with the ``blogs`` collection in +the MongoDB database. This code adds the required ``author`` field and sets its +value to the ``user._id``. + +To add the values of the ``name`` and ``email`` fields to the ``author`` field +for the article, you can use the Mongoose ``populate()`` method. Add the +following code to ``index.js`` to populate this data: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-populate-author + :end-before: end-populate-author + + .. output:: + :language: console + :visible: false + + Article Populated: { + _id: new ObjectId('...'), + title: 'Awesome Post!', + slug: 'awesome-post', + published: false, + author: { + _id: new ObjectId('...'), + name: 'Jess Garica', + email: 'jgarcia@email.com', + __v: 0 + }, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + createdAt: 2025-05-15T18:04:28.590Z, + comments: [], + __v: 0 + } + +This populates the data for the ``author`` field in the data for this article. +Mongoose uses the MongoDB ``$lookup`` method to do this under the hood. + +Middleware +---------- + +In Mongoose, middleware are functions that run before, and, or during the +execution of asynchronous functions at the schema level. + +To use middleware in this project, go to the ``Blog.js`` file. Here you can set +the ``updated`` date field to update every time an article is saved or updated +by using middleware. + +Add the following code to a line below your ``blogSchema`` declaration: + +.. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js + :language: javascript + :start-after: start-blogSchema-middleware + :end-before: end-blogSchema-middleware + :dedent: + +Go to the ``index.js`` file and then add the following code to find an article, +update the title, and then save the updated article: + +.. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-middleware-update + :end-before: end-middleware-update + + .. output:: + :language: console + :visible: false + + Article Updated: { + _id: new ObjectId('...'), + title: 'Updated Title', + slug: 'awesome-post', + published: false, + author: new ObjectId('...'), + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + createdAt: 2025-05-15T18:04:28.590Z, + comments: [], + __v: 0, + updated: 2025-05-15T18:18:30.249Z + } + +When this runs, the returned article includes an ``updated`` date. + +Besides the ``pre()`` middleware function, Mongoose also offers a ``post()`` +middleware function. + +Resources and Next Steps +------------------------ + +You now have a sample project that uses Mongoose to perform CRUD operations on a +MongoDB collection. From here, you can choose to build on this project to use +additional methods or try building more complex queries. + +To learn more about using Mongoose with MongoDB, see the `Mongoose documentation +`__. From eb39e54a6731ff001f6f545b1f1a61c8230fd8a9 Mon Sep 17 00:00:00 2001 From: Stephanie Aurelio Date: Thu, 15 May 2025 11:45:02 -0700 Subject: [PATCH 02/20] edits --- .../mongoose-get-started-blogSchema.js | 6 ++++ .../mongoose-get-started-multiple-schemas.js | 4 +++ .../integrations/mongoose-schema-example.js | 2 +- source/integrations/mongoose-get-started.txt | 36 +++++++++---------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/source/includes/integrations/mongoose-get-started-blogSchema.js b/source/includes/integrations/mongoose-get-started-blogSchema.js index 8aa0423b7..893e24574 100644 --- a/source/includes/integrations/mongoose-get-started-blogSchema.js +++ b/source/includes/integrations/mongoose-get-started-blogSchema.js @@ -19,27 +19,33 @@ console.log('Created article:', article); // end-insert // start-update +// Updates the title of the article article.title = "The Most Awesomest Post!!"; await article.save(); console.log('Updated Article:', article); // end-update // start-find-by-id +// Finds the article by its ID. Replace with the objectId of the article. const articleFound = await Blog.findById("").exec(); console.log('Found Article by ID:', articleFound); // end-find-by-id // start-project-fields +// Finds the article by its ID and projects only the title, slug, and content fields. +// Replace with the objectId of the article. const articleProject = await Blog.findById("", "title slug content").exec(); console.log('Projected Article:', articleProject); // end-project-fields // start-delete-one +// Deletes one article with the slug "awesome-post". const blogOne = await Blog.deleteOne({ slug: "awesome-post" }); console.log('Deleted One Blog:', blogOne); // end-delete-one // start-delete-many +// Deletes all articles with the slug "awesome-post". const blogMany = await Blog.deleteMany({ slug: "awesome-post" }); console.log('Deleted Many Blogs:', blogMany); // end-delete-many \ No newline at end of file diff --git a/source/includes/integrations/mongoose-get-started-multiple-schemas.js b/source/includes/integrations/mongoose-get-started-multiple-schemas.js index e2d99d9f5..bd532eb56 100644 --- a/source/includes/integrations/mongoose-get-started-multiple-schemas.js +++ b/source/includes/integrations/mongoose-get-started-multiple-schemas.js @@ -7,11 +7,13 @@ import User from './model/User.js'; mongoose.connect(""); // start-article-with-author +// Create a new user const user = await User.create({ name: 'Jess Garica', email: 'jgarcia@email.com', }); +// Creates a new blog post that references the user as the author const articleAuthor = await Blog.create({ title: 'Awesome Post!', slug: 'Awesome-Post', @@ -24,11 +26,13 @@ console.log('Article with Author:', articleAuthor); // end-article-with-author // start-populate-author +// Populates the author field with user data const articlePopulate = await Blog.findOne({ title: "Awesome Post!" }).populate("author"); console.log('Article Populated:', articlePopulate); // end-populate-author // start-middleware-update +// Middleware to update the updated field before saving const articleUpdated = await Blog.findById("68262cac638b7ec7ed0a086b").exec(); articleUpdated.title = "Updated Title"; await articleUpdated.save(); diff --git a/source/includes/integrations/mongoose-schema-example.js b/source/includes/integrations/mongoose-schema-example.js index 9b936d1b0..d519251ae 100644 --- a/source/includes/integrations/mongoose-schema-example.js +++ b/source/includes/integrations/mongoose-schema-example.js @@ -17,5 +17,5 @@ const blog = new Schema({ }] }); // end-schema-example -const Blog = model('Blog', blogSchema); +const Blog = model('Blog', blog); export default Blog; \ No newline at end of file diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 14105b233..a49770de5 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -24,9 +24,9 @@ Overview Mongoose is an Object Data Modeling (ODM) library for MongoDB. You can use Mongoose to help with data modeling, schema enforcement, model validation, and general data manipulation. Because MongoDB has a flexible data model that allows -you to easily alter and update databases in the future, there aren't rigid -schemas. Mongoose enforces a semi-regid schema from the beginning. When you use -Mongoose, you must define a schema and model. +you to alter and update databases in the future, there aren't rigid schemas. +Mongoose enforces a semi-regid schema from the beginning. When you use Mongoose, +you must define a schema and model. In this tutorial, you will perform the following actions: @@ -38,7 +38,7 @@ In this tutorial, you will perform the following actions: - Validate your data - Use multiple schemas and middleware -You will also learn other useful methods to grow your experience using Mongoose with MongoDB. +You will also learn additional methods to grow your experience using Mongoose with MongoDB. Schemas ------- @@ -117,7 +117,7 @@ and install the necessary dependencies: npm i -D nodemon Open your project in your preferred code editor. This tutorial uses ES Modules -instead of CommonJS. You need to add the module type to use ES Modules. Go to +instead of CommonJS. You must add the ``module`` type to use ES Modules. Go to the package.json file and add the following code: .. code-block:: json @@ -361,8 +361,8 @@ Additional Methods Mongoose includes several helper methods that are abstracted from regular MongoDB methods. In this section, you can find examples of some of these -methods. You don't need to add these methods to your ``index.js`` file to proceed -with the tutorial, but they are helpful to reference. +methods. These methods are not used specifically in this tutorial, but they are +helpful to reference when getting started with Mongoose. exists() ~~~~~~~~ @@ -405,11 +405,11 @@ after your query, as shown in the following example: Validate Your Data ------------------ -If you refer to the schema, note that the articles inserted so far have not -contained the ``author``, ``dates``, or ``comments`` fields even though these fields are -included in the schema. This is because although you defined the structure of -your document, you have not defined which fields are required. Without defining -the required fields, you can omit any fields. +The articles inserted so far have not contained the ``author``, ``dates``, or +``comments`` fields, even though these fields are included in the schema. This is +because although you defined the structure of your document, you have not +defined which fields are required. Without defining the required fields, you can +omit any fields. To add data validation and define these requirements, update the schema in ``Blog.js`` like the following: @@ -429,7 +429,7 @@ its value. ``value: {type: String}``. You can use several validation methods with Mongoose. For example, you can set -``required`` to true on any fields that you would like to require. +``required`` to true on any fields that you want to require. You can also validate the type and the formatting. In the preceding code, the ``slug`` field is defined as a ``string`` that is always in ``lowercase``. This @@ -448,7 +448,7 @@ Multiple Schemas ---------------- Now that you have validation on your blog schema, and the author field is -``required``, you need to update ``index.js`` to include the author. To do this, +``required``, you must update ``index.js`` to include the author. To do this, you can create a separate schema. In the model folder, create a new file named ``User.js``. Add the following code to @@ -458,8 +458,8 @@ this file: :language: javascript :dedent: -To reference blog schema, update the ``Blog.js`` file to include the following -code: +To reference this new user model in the blog schema, update the ``Blog.js`` file +to include the following code: .. code-block:: javascript @@ -500,7 +500,7 @@ the following code to the top of the file to import the user model: :end-before: end-user-import Since you added field validation to the blog schema, the previous code to -insert, update, and delete blogs, as well as to specify fields to project, won't +insert, update, and delete blogs, and to specify fields to project, won't pass the validation and the application will error. Replace the existing code with the following code to create a new user, and then @@ -532,7 +532,7 @@ following code: __v: 0 } -The preceding code adds a ``users`` collection along with the ``blogs`` collection in +The preceding code adds a ``users`` collection with the ``blogs`` collection in the MongoDB database. This code adds the required ``author`` field and sets its value to the ``user._id``. From 1d1dd8a116a123033e43bd70a29030be3a12ee74 Mon Sep 17 00:00:00 2001 From: Stephanie Aurelio Date: Thu, 15 May 2025 14:43:50 -0700 Subject: [PATCH 03/20] vale fixes and add to landing page integrations section --- source/index.txt | 1 + source/integrations/mongoose-get-started.txt | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/index.txt b/source/index.txt index e366eaf5f..4fbe707b5 100644 --- a/source/index.txt +++ b/source/index.txt @@ -153,6 +153,7 @@ For more information about using ODMs with MongoDB, see the following resources: - :website:`MongoDB ORMs, ODMs, and Libraries ` - `Mongoose `__ official documentation +- :ref:`` tutorial - `Prisma `__ official documentation Packages diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index a49770de5..bdbee6b1f 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -38,8 +38,6 @@ In this tutorial, you will perform the following actions: - Validate your data - Use multiple schemas and middleware -You will also learn additional methods to grow your experience using Mongoose with MongoDB. - Schemas ------- @@ -629,8 +627,9 @@ Resources and Next Steps ------------------------ You now have a sample project that uses Mongoose to perform CRUD operations on a -MongoDB collection. From here, you can choose to build on this project to use -additional methods or try building more complex queries. +MongoDB collection. From here, you can choose to build on this project to include +more complex queries, or you can use this project as a reference for your own +applications. To learn more about using Mongoose with MongoDB, see the `Mongoose documentation `__. From 4129b7d47812e29dab2eee96684d611ed9c48510 Mon Sep 17 00:00:00 2001 From: Stephanie Aurelio Date: Thu, 15 May 2025 15:03:18 -0700 Subject: [PATCH 04/20] edits --- source/integrations/mongoose-get-started.txt | 33 +++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index bdbee6b1f..7e14e2ebb 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -116,7 +116,7 @@ and install the necessary dependencies: Open your project in your preferred code editor. This tutorial uses ES Modules instead of CommonJS. You must add the ``module`` type to use ES Modules. Go to -the package.json file and add the following code: +the ``package.json`` file and add the following code: .. code-block:: json @@ -159,7 +159,7 @@ folder/file. Open this file and add the following code: :dedent: You now have your first model and schema set up, and you can start inserting -data in the database. +data into the database. Insert Data ----------- @@ -249,11 +249,11 @@ Find Data --------- To update a specific document, you can use the Mongoose ``findById()`` method to get -a document by its ObjectId. +a document by its ``ObjectId``. Add following code to your ``index.js`` file to find a specific article by its -ObjectId, replacing the ```` placeholder with the ObjectId for the -document that you inserted previously: +``ObjectId``, replacing the ```` placeholder with the ``ObjectId`` +value for the document that you inserted previously: .. io-code-block:: :copyable: @@ -291,8 +291,8 @@ Like with the {+driver-short+}, you can use Mongoose to project only the fields you need. The following code specifies to only project the ``title``, ``slug``, and ``content`` fields. -Add the following code to your ``index.js`` file, replacing the -```` placeholder with the ObjectId for the document that you inserted +Add the following code to your ``index.js`` file, replacing the ```` +placeholder with the ``ObjectId`` value for the document that you inserted previously: .. io-code-block:: @@ -354,6 +354,8 @@ To delete multiple articles, you can add the following code: Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } +.. _node-mongoose-get-started-additional-methods: + Additional Methods ------------------ @@ -365,7 +367,7 @@ helpful to reference when getting started with Mongoose. exists() ~~~~~~~~ -The ``exists()`` method returns either null or the ObjectId of a document that +The ``exists()`` method returns either null or the ``ObjectId`` of a document that matches the provided query. The following is an example of matching an article based on the ``author`` field: @@ -384,9 +386,10 @@ operation using ``findOne()`` and the equivalent approach using the ``where()`` .. code-block:: javascript const blogFind = await Blog.findOne({ author: "Jess Garcia" }); + console.log(blogFind); const blogWhere = await Blog.where("author").equals("Jess Garcia"); - console.log(blogWhere) + console.log(blogWhere); You can use either method to perform find operations. You can also chain multiple ``where()`` methods to build increasingly complex queries. @@ -396,8 +399,8 @@ after your query, as shown in the following example: .. code-block:: javascript - const blog = await Blog.where("author").equals("Jess Garcia").select("title author") - console.log(blog) + const blog = await Blog.where("author").equals("Jess Garcia").select("title author"); + console.log(blog); Validate Your Data @@ -449,7 +452,7 @@ Now that you have validation on your blog schema, and the author field is ``required``, you must update ``index.js`` to include the author. To do this, you can create a separate schema. -In the model folder, create a new file named ``User.js``. Add the following code to +In the ``model`` folder, create a new file named ``User.js``. Add the following code to this file: .. literalinclude:: /includes/integrations/mongoose-userSchema.js @@ -627,9 +630,9 @@ Resources and Next Steps ------------------------ You now have a sample project that uses Mongoose to perform CRUD operations on a -MongoDB collection. From here, you can choose to build on this project to include -more complex queries, or you can use this project as a reference for your own -applications. +MongoDB collection. From here, you can choose to build on this project to +incorporate more :ref:`Mongoose methods +` and build more complex queries. To learn more about using Mongoose with MongoDB, see the `Mongoose documentation `__. From 098022e8fca4dbf22e05b8a2e05d3b44921d505c Mon Sep 17 00:00:00 2001 From: Stephanie Aurelio Date: Thu, 15 May 2025 15:06:08 -0700 Subject: [PATCH 05/20] update title --- source/integrations/mongoose-get-started.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 7e14e2ebb..8dcb72ee3 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -354,10 +354,10 @@ To delete multiple articles, you can add the following code: Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } -.. _node-mongoose-get-started-additional-methods: +.. _node-mongoose-get-started-helper-methods: -Additional Methods ------------------- +Helper Methods +-------------- Mongoose includes several helper methods that are abstracted from regular MongoDB methods. In this section, you can find examples of some of these @@ -631,8 +631,8 @@ Resources and Next Steps You now have a sample project that uses Mongoose to perform CRUD operations on a MongoDB collection. From here, you can choose to build on this project to -incorporate more :ref:`Mongoose methods -` and build more complex queries. +incorporate :ref:`Mongoose helper methods +` and build more complex queries. To learn more about using Mongoose with MongoDB, see the `Mongoose documentation `__. From df13c4a1cdddb838124dd96c50f84289200067bd Mon Sep 17 00:00:00 2001 From: Stephanie Aurelio Date: Thu, 15 May 2025 15:35:21 -0700 Subject: [PATCH 06/20] update section heading hierarchy --- source/integrations/mongoose-get-started.txt | 24 ++++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 8dcb72ee3..4c199a5bc 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -15,7 +15,7 @@ Get Started with Mongoose .. contents:: On this page :local: :backlinks: none - :depth: 1 + :depth: 2 :class: singlecol Overview @@ -39,7 +39,7 @@ In this tutorial, you will perform the following actions: - Use multiple schemas and middleware Schemas -------- +~~~~~~~ A schema defines the structure of your collection documents. A Mongoose schema maps directly to a MongoDB collection. @@ -67,7 +67,7 @@ following types are permitted: - Map Models ------- +~~~~~~ Models take your schema and apply it to each document in its collection. Models are responsible for all document interactions such as create, read, update, and @@ -158,11 +158,15 @@ folder/file. Open this file and add the following code: :language: javascript :dedent: +Perform CRUD Operations +----------------------- + You now have your first model and schema set up, and you can start inserting -data into the database. +data into the database. The following sections show you how to perform CRUD +operations using Mongoose. Insert Data ------------ +~~~~~~~~~~~ Go to ``index.js`` and add the following import statement to the top of your file: @@ -216,7 +220,7 @@ To run the code, use the following command in your terminal: insert multiple articles into your database. Update Data ------------ +~~~~~~~~~~~ To update data, you can directly edit the local object with Mongoose. Then, you can use the ``save()`` method to write the update to the database. Add the @@ -246,7 +250,7 @@ following code to update the article you inserted in the previous section: } Find Data ---------- +~~~~~~~~~ To update a specific document, you can use the Mongoose ``findById()`` method to get a document by its ``ObjectId``. @@ -285,7 +289,7 @@ value for the document that you inserted previously: see the `Promises guide `__ in the Mongoose documentation. Specify Document Fields ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ Like with the {+driver-short+}, you can use Mongoose to project only the fields that you need. The following code specifies to only project the ``title``, ``slug``, and @@ -315,7 +319,7 @@ previously: } Delete Data ------------ +~~~~~~~~~~~ Mongoose uses the ``deleteOne()`` and ``deleteMany()`` methods to delete data from a collection. You can specify the field of the document you want to delete and @@ -621,7 +625,7 @@ update the title, and then save the updated article: updated: 2025-05-15T18:18:30.249Z } -When this runs, the returned article includes an ``updated`` date. +When you run the application, the returned article includes an ``updated`` date. Besides the ``pre()`` middleware function, Mongoose also offers a ``post()`` middleware function. From dfe6995eb52f3e895a50a465ec1f7943c3ffe302 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Wed, 28 May 2025 11:05:28 -0400 Subject: [PATCH 07/20] steps test --- source/integrations/mongoose-get-started.txt | 103 ++++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 4c199a5bc..739de3943 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -25,7 +25,7 @@ Mongoose is an Object Data Modeling (ODM) library for MongoDB. You can use Mongoose to help with data modeling, schema enforcement, model validation, and general data manipulation. Because MongoDB has a flexible data model that allows you to alter and update databases in the future, there aren't rigid schemas. -Mongoose enforces a semi-regid schema from the beginning. When you use Mongoose, +However, Mongoose enforces a semi-rigid schema from the beginning, so you must define a schema and model. In this tutorial, you will perform the following actions: @@ -99,76 +99,77 @@ Before you begin this tutorial, perform the following actions: ` guide. - Install `Node.js `__ {+min-node-version+} or later. -Set Up Your Environment ------------------------ +.. procedure:: + :style: connected -This tutorial uses npm to install dependencies and nodemon to run the code -locally. Run the following commands in your terminal to initialize your project -and install the necessary dependencies: + .. step:: Set up your environment. -.. code-block:: bash + This tutorial uses npm to install dependencies and nodemon to run the code + locally. Run the following commands in your terminal to initialize your + project and install the necessary dependencies: - mkdir mongodb-mongoose - cd mongodb-mongoose - npm init -y - npm i mongoose - npm i -D nodemon + .. code-block:: bash -Open your project in your preferred code editor. This tutorial uses ES Modules -instead of CommonJS. You must add the ``module`` type to use ES Modules. Go to -the ``package.json`` file and add the following code: + mkdir mongodb-mongoose + cd mongodb-mongoose + npm init -y + npm i mongoose + npm i -D nodemon -.. code-block:: json + Open your project in your preferred code editor. This tutorial uses ES + Modules instead of CommonJS. You must add the ``module`` type to use ES + Modules. Go to the ``package.json`` file and add the following code: - ... - "scripts": { - "dev": "nodemon index.js" - }, - "type": "module", - ... + .. code-block:: json -Connect to MongoDB ------------------- + ... + "scripts": { + "dev": "nodemon index.js" + }, + "type": "module", + ... -In the root level of your project, create a file named ``index.js`` and add the -following code to the top of the file: + .. step:: Connect to MongoDB -.. code-block:: javascript + In the root level of your project, create a file named ``index.js`` and + add the following code to the top of the file: - import mongoose from 'mongoose'; + .. code-block:: javascript - mongoose.connect("") + import mongoose from 'mongoose'; -Replace the ```` placeholder with your MongoDB Atlas -connection string. For more information on how to find your connection string, -see the :atlas:`Connect to Your Cluster ` -tutorial in the Atlas documentation. + mongoose.connect("") -Create a Schema and Model -------------------------- + Replace the ```` placeholder with your MongoDB Atlas + connection string. For more information on how to find your connection + string, see the :atlas:`Connect to Your Cluster + ` tutorial in the Atlas documentation. -Before you start adding and updating data in MongoDB, you must create a schema -and model. + .. step:: Create a Schema and Model -With Mongoose, you create a schema model file for each schema that is needed. To -do this, use the folder/file structure. Create the ``model/Blog.js`` -folder/file. Open this file and add the following code: + Before you start adding and updating data in MongoDB, you must create a + schema and model. -.. literalinclude:: /includes/integrations/mongoose-blogSchema.js - :language: javascript - :dedent: + With Mongoose, you create a schema model file for each schema that is + needed. To do this, use the folder/file structure. Create the + ``model/Blog.js`` folder/file. Open this file and add the following code: -Perform CRUD Operations ------------------------ + .. literalinclude:: /includes/integrations/mongoose-blogSchema.js + :language: javascript + :dedent: -You now have your first model and schema set up, and you can start inserting -data into the database. The following sections show you how to perform CRUD -operations using Mongoose. + .. step:: Perform CRUD Operations -Insert Data -~~~~~~~~~~~ + You now have your first model and schema set up, and you can start + inserting data into the database. The following sections show you how to + perform CRUD operations using Mongoose. + + .. procedure:: + :style: connected + + .. step:: Insert Data -Go to ``index.js`` and add the following import statement to the top of your file: + Go to ``index.js`` and add the following import statement to the top of your file: .. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js :language: javascript From 53f0b82103a20c6dae8a727bc140d04c4b5ccb90 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Wed, 28 May 2025 11:17:14 -0400 Subject: [PATCH 08/20] title test --- source/integrations/mongoose-get-started.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 739de3943..61af96374 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -167,9 +167,10 @@ Before you begin this tutorial, perform the following actions: .. procedure:: :style: connected - .. step:: Insert Data + Insert Data + ~~~~~~~~~~~ - Go to ``index.js`` and add the following import statement to the top of your file: + Go to ``index.js`` and add the following import statement to the top of your file: .. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js :language: javascript From 8cf760402f71dfc39e6849663bcad7d4e6713c96 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Wed, 28 May 2025 15:39:31 -0400 Subject: [PATCH 09/20] step formatting --- source/integrations/mongoose-get-started.txt | 811 ++++++++++--------- 1 file changed, 407 insertions(+), 404 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 61af96374..e7b79118c 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -89,6 +89,54 @@ The following example shows how to declare a model named ``Blog`` that uses the In the preceding example, ``Blog`` translates to the ``blogs`` collection in MongoDB. +.. _node-mongoose-get-started-helper-methods: + +Helper Methods +~~~~~~~~~~~~~~ + +Mongoose includes several helper methods that are abstracted from regular +MongoDB methods. In this section, you can find examples of some of these +methods. These methods are not used specifically in this tutorial, but they are +helpful to reference when getting started with Mongoose. + +exists() +```````` + +The ``exists()`` method returns either null or the ``ObjectId`` of a document that +matches the provided query. The following is an example of matching an article +based on the ``author`` field: + +.. code-block:: javascript + + const blog = await Blog.exists({ author: 'Jess Garcia' }); + console.log(blog); + +where() +``````` + +Mongoose has a unique style of querying data. The ``where()`` method allows you to +chain and build queries. The following is an example of performing a find +operation using ``findOne()`` and the equivalent approach using the ``where()`` method: + +.. code-block:: javascript + + const blogFind = await Blog.findOne({ author: "Jess Garcia" }); + console.log(blogFind); + + const blogWhere = await Blog.where("author").equals("Jess Garcia"); + console.log(blogWhere); + +You can use either method to perform find operations. You can also chain +multiple ``where()`` methods to build increasingly complex queries. + +To include projection when using the ``where()`` method, chain the ``select()`` method +after your query, as shown in the following example: + +.. code-block:: javascript + + const blog = await Blog.where("author").equals("Jess Garcia").select("title author"); + console.log(blog); + Prerequisites ------------- @@ -172,465 +220,420 @@ Before you begin this tutorial, perform the following actions: Go to ``index.js`` and add the following import statement to the top of your file: -.. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-blogSchema-import - :end-before: end-blogSchema-import - :dedent: - -Add the following code below the line that contains your connection string: - -.. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-insert - :end-before: end-insert - :dedent: - -The preceding code uses the Mongoose ``create()`` method to instantiate the object -representing a blog article, and then saves it to the database. The returned -document logs to the console, including its ``_id``. Take note of this ``_id`` for use -in future steps. - -To run the code, use the following command in your terminal: - -.. io-code-block:: - :copyable: - - .. input:: - :language: bash - - npm run dev - - .. output:: - :language: console - :visible: false - - Created article: { - title: 'Awesome Post!', - slug: 'awesome-post', - published: true, - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - _id: new ObjectId('...'), - comments: [], - __v: 0 - } - -.. note:: - - When you use nodemon, the code runs every time you save a file. Saving will - insert multiple articles into your database. - -Update Data -~~~~~~~~~~~ - -To update data, you can directly edit the local object with Mongoose. Then, you -can use the ``save()`` method to write the update to the database. Add the -following code to update the article you inserted in the previous section: - -.. io-code-block:: - :copyable: - - .. input:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-update - :end-before: end-update - - .. output:: - :language: console - :visible: false - - Updated Article: { - title: 'The Most Awesomest Post!!', - slug: 'awesome-post', - published: true, - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - _id: new ObjectId('...'), - comments: [], - __v: 0 - } - -Find Data -~~~~~~~~~ - -To update a specific document, you can use the Mongoose ``findById()`` method to get -a document by its ``ObjectId``. - -Add following code to your ``index.js`` file to find a specific article by its -``ObjectId``, replacing the ```` placeholder with the ``ObjectId`` -value for the document that you inserted previously: - -.. io-code-block:: - :copyable: - - .. input:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-find-by-id - :end-before: end-find-by-id - - .. output:: - :language: console - :visible: false - - Found Article by ID: { - _id: new ObjectId('68261c9dae39e390341c367c'), - title: 'The Most Awesomest Post!!', - slug: 'awesome-post', - published: true, - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - comments: [], - __v: 0 - } - -.. note:: - - The Mongoose ``exec()`` function is an option of the ``findById()`` method that - returns a promise. To learn more about working with promises and Mongoose, - see the `Promises guide `__ in the Mongoose documentation. - -Specify Document Fields -~~~~~~~~~~~~~~~~~~~~~~~ + .. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-blogSchema-import + :end-before: end-blogSchema-import + :dedent: -Like with the {+driver-short+}, you can use Mongoose to project only the fields that -you need. The following code specifies to only project the ``title``, ``slug``, and -``content`` fields. + Add the following code below the line that contains your connection string: -Add the following code to your ``index.js`` file, replacing the ```` -placeholder with the ``ObjectId`` value for the document that you inserted -previously: + .. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-insert + :end-before: end-insert + :dedent: -.. io-code-block:: - :copyable: + The preceding code uses the Mongoose ``create()`` method to instantiate + the object representing a blog article, and then saves it to the database. + The returned document logs to the console, including its ``_id``. Take + note of this ``_id`` for use in future steps. - .. input:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-project-fields - :end-before: end-project-fields + To run the code, use the following command in your terminal: - .. output:: - :language: console - :visible: false + .. io-code-block:: + :copyable: - Projected Article: { - _id: new ObjectId('...'), - title: 'The Most Awesomest Post!!', - slug: 'awesome-post', - content: 'This is the best post ever' - } + .. input:: + :language: bash -Delete Data -~~~~~~~~~~~ + npm run dev -Mongoose uses the ``deleteOne()`` and ``deleteMany()`` methods to delete data from a -collection. You can specify the field of the document you want to delete and -pass that field to the method that you choose. + .. output:: + :language: console + :visible: false -Add the following code to your index.js file to delete one article from the -database: + Created article: { + title: 'Awesome Post!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + _id: new ObjectId('...'), + comments: [], + __v: 0 + } + + .. note:: -.. io-code-block:: - :copyable: + When you use nodemon, the code runs every time you save a file. Saving will + insert multiple articles into your database. - .. input:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-delete-one - :end-before: end-delete-one + Update Data + ~~~~~~~~~~~ - .. output:: - :language: console - :visible: false + To update data, you can directly edit the local object with Mongoose. + Then, you can use the ``save()`` method to write the update to the + database. Add the following code to update the article you inserted in the + previous section: + + .. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-update + :end-before: end-update + + .. output:: + :language: console + :visible: false + + Updated Article: { + title: 'The Most Awesomest Post!!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + _id: new ObjectId('...'), + comments: [], + __v: 0 + } + + Find Data + ~~~~~~~~~ + + To update a specific document, you can use the Mongoose ``findById()`` + method to get a document by its ``ObjectId``. + + Add following code to your ``index.js`` file to find a specific article by + its ``ObjectId``, replacing the ```` placeholder with the + ``ObjectId`` value for the document that you inserted previously: + + .. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-find-by-id + :end-before: end-find-by-id + + .. output:: + :language: console + :visible: false + + Found Article by ID: { + _id: new ObjectId('68261c9dae39e390341c367c'), + title: 'The Most Awesomest Post!!', + slug: 'awesome-post', + published: true, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + comments: [], + __v: 0 + } + + .. note:: + + The Mongoose ``exec()`` function is an option of the ``findById()`` + method that returns a promise. To learn more about working with + promises and Mongoose, see the `Promises guide + `__ in the Mongoose + documentation. + + Specify Document Fields + ~~~~~~~~~~~~~~~~~~~~~~~ - Deleted One Blog: { acknowledged: true, deletedCount: 1 } + Like with the {+driver-short+}, you can use Mongoose to project only the + fields that you need. The following code specifies to only project the + ``title``, ``slug``, and ``content`` fields. -To delete multiple articles, you can add the following code: + Add the following code to your ``index.js`` file, replacing the ```` placeholder with the ``ObjectId`` value for the document that you + inserted previously: -.. io-code-block:: - :copyable: + .. io-code-block:: + :copyable: - .. input:: /includes/integrations/mongoose-get-started-blogSchema.js - :language: javascript - :start-after: start-delete-many - :end-before: end-delete-many + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-project-fields + :end-before: end-project-fields - .. output:: - :language: console - :visible: false + .. output:: + :language: console + :visible: false - Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } + Projected Article: { + _id: new ObjectId('...'), + title: 'The Most Awesomest Post!!', + slug: 'awesome-post', + content: 'This is the best post ever' + } -.. _node-mongoose-get-started-helper-methods: + Delete Data + ~~~~~~~~~~~ -Helper Methods --------------- + Mongoose uses the ``deleteOne()`` and ``deleteMany()`` methods to delete + data from a collection. You can specify the field of the document you want + to delete and pass that field to the method that you choose. -Mongoose includes several helper methods that are abstracted from regular -MongoDB methods. In this section, you can find examples of some of these -methods. These methods are not used specifically in this tutorial, but they are -helpful to reference when getting started with Mongoose. + Add the following code to your index.js file to delete one article from the + database: -exists() -~~~~~~~~ + .. io-code-block:: + :copyable: -The ``exists()`` method returns either null or the ``ObjectId`` of a document that -matches the provided query. The following is an example of matching an article -based on the ``author`` field: + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-delete-one + :end-before: end-delete-one -.. code-block:: javascript + .. output:: + :language: console + :visible: false - const blog = await Blog.exists({ author: 'Jess Garcia' }); - console.log(blog); + Deleted One Blog: { acknowledged: true, deletedCount: 1 } -where() -~~~~~~~ + To delete multiple articles, you can add the following code: -Mongoose has a unique style of querying data. The ``where()`` method allows you to -chain and build queries. The following is an example of performing a find -operation using ``findOne()`` and the equivalent approach using the ``where()`` method: + .. io-code-block:: + :copyable: -.. code-block:: javascript + .. input:: /includes/integrations/mongoose-get-started-blogSchema.js + :language: javascript + :start-after: start-delete-many + :end-before: end-delete-many - const blogFind = await Blog.findOne({ author: "Jess Garcia" }); - console.log(blogFind); + .. output:: + :language: console + :visible: false - const blogWhere = await Blog.where("author").equals("Jess Garcia"); - console.log(blogWhere); + Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } -You can use either method to perform find operations. You can also chain -multiple ``where()`` methods to build increasingly complex queries. + .. step:: Validate Your Data -To include projection when using the ``where()`` method, chain the ``select()`` method -after your query, as shown in the following example: + The articles inserted so far have not contained the ``author``, ``dates``, + or ``comments`` fields, even though these fields are included in the + schema. This is because although you defined the structure of your + document, you have not defined which fields are required. Without defining + the required fields, you can omit any fields. -.. code-block:: javascript + To add data validation and define these requirements, update the schema in + ``Blog.js`` like the following: - const blog = await Blog.where("author").equals("Jess Garcia").select("title author"); - console.log(blog); + .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js + :language: javascript + :start-after: start-blogSchema + :end-before: end-blogSchema + :dedent: + In Mongoose, when you include validation on a field, you must pass an + object as its value. -Validate Your Data ------------------- + .. tip:: -The articles inserted so far have not contained the ``author``, ``dates``, or -``comments`` fields, even though these fields are included in the schema. This is -because although you defined the structure of your document, you have not -defined which fields are required. Without defining the required fields, you can -omit any fields. + When you use schemas with Mongoose, ``value: String`` is the same as + ``value: {type: String}``. -To add data validation and define these requirements, update the schema in -``Blog.js`` like the following: + You can use several validation methods with Mongoose. For example, you can + set ``required`` to true on any fields that you want to require. -.. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js - :language: javascript - :start-after: start-blogSchema - :end-before: end-blogSchema - :dedent: + You can also validate the type and the formatting. In the preceding code, + the ``slug`` field is defined as a ``string`` that is always in + ``lowercase``. This validation takes the slug input and converts it to + lowercase before saving the document to the database. -In Mongoose, when you include validation on a field, you must pass an object as -its value. + For the ``createdAt`` date field, you can set the default by using an + arrow function. This field is also specified to be impossible to change + later by setting ``immutable`` to ``true``. -.. tip:: + .. note:: - When you use schemas with Mongoose, ``value: String`` is the same as - ``value: {type: String}``. + Validators only run on the ``create()`` and ``save()`` methods. -You can use several validation methods with Mongoose. For example, you can set -``required`` to true on any fields that you want to require. + .. step:: Introduce Multiple Schemas -You can also validate the type and the formatting. In the preceding code, the -``slug`` field is defined as a ``string`` that is always in ``lowercase``. This -validation takes the slug input and converts it to lowercase before saving the -document to the database. + Now that you have validation on your blog schema, and the author field is + ``required``, you must update ``index.js`` to include the author. To do + this, you can create a separate schema. -For the ``createdAt`` date field, you can set the default by using an arrow function. -This field is also specified to be impossible to change later by setting -``immutable`` to ``true``. + In the ``model`` folder, create a new file named ``User.js``. Add the + following code to this file: -.. note:: + .. literalinclude:: /includes/integrations/mongoose-userSchema.js + :language: javascript + :dedent: - Validators only run on the ``create()`` and ``save()`` methods. + To reference this new user model in the blog schema, update the + ``Blog.js`` file to include the following code: -Multiple Schemas ----------------- + .. code-block:: javascript -Now that you have validation on your blog schema, and the author field is -``required``, you must update ``index.js`` to include the author. To do this, -you can create a separate schema. + import mongoose from 'mongoose'; + const { Schema, SchemaTypes, model } = mongoose; -In the ``model`` folder, create a new file named ``User.js``. Add the following code to -this file: + const blogSchema = new Schema({ + ... + author: { + type: SchemaTypes.ObjectId, + ref: 'User', + required: true, + }, + ..., + comments: [{ + user: { + type: SchemaTypes.ObjectId, + ref: 'User', + required: true, + }, + content: String, + votes: Number + }]; + }); + ... -.. literalinclude:: /includes/integrations/mongoose-userSchema.js - :language: javascript - :dedent: -To reference this new user model in the blog schema, update the ``Blog.js`` file -to include the following code: + The preceding code sets the ``author`` and ``comments.user`` to + ``SchemaTypes.ObjectId`` and adds a ``ref``, or reference, to the user + model. Be sure to destructure ``SchemaTypes`` from Mongoose at the top of + the file below the import statement. -.. code-block:: javascript + To use the new user model in your application, go to the ``index.js`` + file. Add the following code to the top of the file to import the user + model: - import mongoose from 'mongoose'; - const { Schema, SchemaTypes, model } = mongoose; - - const blogSchema = new Schema({ - ... - author: { - type: SchemaTypes.ObjectId, - ref: 'User', - required: true, - }, - ..., - comments: [{ - user: { - type: SchemaTypes.ObjectId, - ref: 'User', - required: true, - }, - content: String, - votes: Number - }]; - }); - ... - - -The preceding code sets the ``author`` and ``comments.user`` to ``SchemaTypes.ObjectId`` and -adds a ``ref``, or reference, to the user model. Be sure to destructure ``SchemaTypes`` -from Mongoose at the top of the file below the import statement. - -To use the new user model in your application, go to the ``index.js`` file. Add -the following code to the top of the file to import the user model: - -.. literalinclude:: /includes/integrations/mongoose-get-started-multiple-schemas.js - :language: javascript - :start-after: start-user-import - :end-before: end-user-import - -Since you added field validation to the blog schema, the previous code to -insert, update, and delete blogs, and to specify fields to project, won't -pass the validation and the application will error. - -Replace the existing code with the following code to create a new user, and then -create a new article that uses this user as the author, as shown in the -following code: - -.. io-code-block:: - :copyable: - - .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js - :language: javascript - :start-after: start-article-with-author - :end-before: end-article-with-author - - .. output:: - :language: console - :visible: false - - Article with Author: { - title: 'Awesome Post!', - slug: 'awesome-post', - published: false, - author: new ObjectId('...'), - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - _id: new ObjectId('...'), - createdAt: 2025-05-15T18:05:23.780Z, - comments: [], - __v: 0 - } - -The preceding code adds a ``users`` collection with the ``blogs`` collection in -the MongoDB database. This code adds the required ``author`` field and sets its -value to the ``user._id``. - -To add the values of the ``name`` and ``email`` fields to the ``author`` field -for the article, you can use the Mongoose ``populate()`` method. Add the -following code to ``index.js`` to populate this data: - -.. io-code-block:: - :copyable: - - .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js - :language: javascript - :start-after: start-populate-author - :end-before: end-populate-author - - .. output:: - :language: console - :visible: false - - Article Populated: { - _id: new ObjectId('...'), - title: 'Awesome Post!', - slug: 'awesome-post', - published: false, - author: { - _id: new ObjectId('...'), - name: 'Jess Garica', - email: 'jgarcia@email.com', - __v: 0 - }, - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - createdAt: 2025-05-15T18:04:28.590Z, - comments: [], - __v: 0 - } - -This populates the data for the ``author`` field in the data for this article. -Mongoose uses the MongoDB ``$lookup`` method to do this under the hood. - -Middleware ----------- - -In Mongoose, middleware are functions that run before, and, or during the -execution of asynchronous functions at the schema level. - -To use middleware in this project, go to the ``Blog.js`` file. Here you can set -the ``updated`` date field to update every time an article is saved or updated -by using middleware. - -Add the following code to a line below your ``blogSchema`` declaration: - -.. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js - :language: javascript - :start-after: start-blogSchema-middleware - :end-before: end-blogSchema-middleware - :dedent: + .. literalinclude:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-user-import + :end-before: end-user-import + + Since you added field validation to the blog schema, the previous code to + insert, update, and delete blogs, and to specify fields to project, won't + pass the validation and the application will error. + + Replace the existing code with the following code to create a new user, + and then create a new article that uses this user as the author, as shown + in the following code: + + .. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-article-with-author + :end-before: end-article-with-author + + .. output:: + :language: console + :visible: false + + Article with Author: { + title: 'Awesome Post!', + slug: 'awesome-post', + published: false, + author: new ObjectId('...'), + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + _id: new ObjectId('...'), + createdAt: 2025-05-15T18:05:23.780Z, + comments: [], + __v: 0 + } + + The preceding code adds a ``users`` collection with the ``blogs`` + collection in the MongoDB database. This code adds the required ``author`` + field and sets its value to the ``user._id``. + + To add the values of the ``name`` and ``email`` fields to the ``author`` + field for the article, you can use the Mongoose ``populate()`` method. Add + the following code to ``index.js`` to populate this data: + + .. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-populate-author + :end-before: end-populate-author + + .. output:: + :language: console + :visible: false + + Article Populated: { + _id: new ObjectId('...'), + title: 'Awesome Post!', + slug: 'awesome-post', + published: false, + author: { + _id: new ObjectId('...'), + name: 'Jess Garica', + email: 'jgarcia@email.com', + __v: 0 + }, + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + createdAt: 2025-05-15T18:04:28.590Z, + comments: [], + __v: 0 + } + + This populates the data for the ``author`` field in the data for this + article. Mongoose uses the MongoDB ``$lookup`` method to do this under the + hood. + + .. step:: Add Middleware + + In Mongoose, middleware are functions that run before, and, or during the + execution of asynchronous functions at the schema level. + + To use middleware in this project, go to the ``Blog.js`` file. Here you + can set the ``updated`` date field to update every time an article is + saved or updated by using middleware. + + Add the following code to a line below your ``blogSchema`` declaration: + + .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js + :language: javascript + :start-after: start-blogSchema-middleware + :end-before: end-blogSchema-middleware + :dedent: -Go to the ``index.js`` file and then add the following code to find an article, -update the title, and then save the updated article: - -.. io-code-block:: - :copyable: - - .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js - :language: javascript - :start-after: start-middleware-update - :end-before: end-middleware-update - - .. output:: - :language: console - :visible: false - - Article Updated: { - _id: new ObjectId('...'), - title: 'Updated Title', - slug: 'awesome-post', - published: false, - author: new ObjectId('...'), - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - createdAt: 2025-05-15T18:04:28.590Z, - comments: [], - __v: 0, - updated: 2025-05-15T18:18:30.249Z - } - -When you run the application, the returned article includes an ``updated`` date. - -Besides the ``pre()`` middleware function, Mongoose also offers a ``post()`` -middleware function. + Go to the ``index.js`` file and then add the following code to find an + article, update the title, and then save the updated article: + + .. io-code-block:: + :copyable: + + .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-middleware-update + :end-before: end-middleware-update + + .. output:: + :language: console + :visible: false + + Article Updated: { + _id: new ObjectId('...'), + title: 'Updated Title', + slug: 'awesome-post', + published: false, + author: new ObjectId('...'), + content: 'This is the best post ever', + tags: [ 'featured', 'announcement' ], + createdAt: 2025-05-15T18:04:28.590Z, + comments: [], + __v: 0, + updated: 2025-05-15T18:18:30.249Z + } + + When you run the application, the returned article includes an ``updated`` + date. + + Besides the ``pre()`` middleware function, Mongoose also offers a + ``post()`` middleware function. Resources and Next Steps ------------------------ From 2a4b6b77e231525c5e9f35e8256c59c2354322ba Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Wed, 28 May 2025 16:23:29 -0400 Subject: [PATCH 10/20] JS feedback --- source/integrations/mongoose-get-started.txt | 80 ++++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index e7b79118c..9f2607dbb 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -102,7 +102,7 @@ helpful to reference when getting started with Mongoose. exists() ```````` -The ``exists()`` method returns either null or the ``ObjectId`` of a document that +The ``exists()`` method returns either ``null`` or the ``ObjectId`` of a document that matches the provided query. The following is an example of matching an article based on the ``author`` field: @@ -111,12 +111,16 @@ based on the ``author`` field: const blog = await Blog.exists({ author: 'Jess Garcia' }); console.log(blog); +For more information, see the `Model.exists() +`__ section of the +Mongoose API documentation. + where() ``````` -Mongoose has a unique style of querying data. The ``where()`` method allows you to -chain and build queries. The following is an example of performing a find -operation using ``findOne()`` and the equivalent approach using the ``where()`` method: +The ``where()`` method allows you to chain and build queries. The following is +an example of performing a find operation by using ``findOne()`` and the equivalent +approach by using the ``where()`` method: .. code-block:: javascript @@ -137,12 +141,16 @@ after your query, as shown in the following example: const blog = await Blog.where("author").equals("Jess Garcia").select("title author"); console.log(blog); +For more information, see the `Model.where() +`__ section of the +Mongoose API documentation. + Prerequisites ------------- Before you begin this tutorial, perform the following actions: -- Set up a MongoDB Atlas account and configure a cluster that is M0 or higher. +- Set up a MongoDB Atlas account and configure a cluster. To view instructions, see the :atlas:`Get Started with Atlas ` guide. - Install `Node.js `__ {+min-node-version+} or later. @@ -152,9 +160,9 @@ Before you begin this tutorial, perform the following actions: .. step:: Set up your environment. - This tutorial uses npm to install dependencies and nodemon to run the code - locally. Run the following commands in your terminal to initialize your - project and install the necessary dependencies: + This tutorial uses `nodemon `__ to + run the code locally. Run the following commands in your terminal to + initialize your project and install the necessary dependencies: .. code-block:: bash @@ -199,8 +207,9 @@ Before you begin this tutorial, perform the following actions: schema and model. With Mongoose, you create a schema model file for each schema that is - needed. To do this, use the folder/file structure. Create the - ``model/Blog.js`` folder/file. Open this file and add the following code: + needed. First, create the a folder called ``model`` to put all your schema + files in, then create your first schema file called ``Blog.js``. Open this + file and add the following code: .. literalinclude:: /includes/integrations/mongoose-blogSchema.js :language: javascript @@ -274,7 +283,9 @@ Before you begin this tutorial, perform the following actions: To update data, you can directly edit the local object with Mongoose. Then, you can use the ``save()`` method to write the update to the - database. Add the following code to update the article you inserted in the + database. + + Add the following code to update the article you inserted in the previous section: .. io-code-block:: @@ -413,14 +424,14 @@ Before you begin this tutorial, perform the following actions: .. step:: Validate Your Data - The articles inserted so far have not contained the ``author``, ``dates``, - or ``comments`` fields, even though these fields are included in the - schema. This is because although you defined the structure of your - document, you have not defined which fields are required. Without defining - the required fields, you can omit any fields. + The articles inserted in the previous steps do not contain the ``author``, + ``dates``, or ``comments`` fields, even though these fields are included + in the schema. This is because although you defined the structure of your + document, you have not defined which fields are required. Any field that + is no defined as required can be omitted. To add data validation and define these requirements, update the schema in - ``Blog.js`` like the following: + ``Blog.js`` as shown in the following example: .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js :language: javascript @@ -437,12 +448,11 @@ Before you begin this tutorial, perform the following actions: ``value: {type: String}``. You can use several validation methods with Mongoose. For example, you can - set ``required`` to true on any fields that you want to require. - - You can also validate the type and the formatting. In the preceding code, - the ``slug`` field is defined as a ``string`` that is always in - ``lowercase``. This validation takes the slug input and converts it to - lowercase before saving the document to the database. + set ``required`` to true on any fields that you want to require. You can + also validate the type and the formatting. In the preceding code, the + ``slug`` field is defined as a ``string`` that is always in ``lowercase``. + This validation takes the slug input and converts it to lowercase before + saving the document to the database. For the ``createdAt`` date field, you can set the default by using an arrow function. This field is also specified to be impossible to change @@ -454,8 +464,8 @@ Before you begin this tutorial, perform the following actions: .. step:: Introduce Multiple Schemas - Now that you have validation on your blog schema, and the author field is - ``required``, you must update ``index.js`` to include the author. To do + Now that you have validation on your blog schema, and the ``author`` field is + ``required``, you must update ``index.js`` to include the ``author``. To do this, you can create a separate schema. In the ``model`` folder, create a new file named ``User.js``. Add the @@ -508,7 +518,7 @@ Before you begin this tutorial, perform the following actions: :start-after: start-user-import :end-before: end-user-import - Since you added field validation to the blog schema, the previous code to + Because you added field validation to the blog schema, the previous code to insert, update, and delete blogs, and to specify fields to project, won't pass the validation and the application will error. @@ -579,13 +589,13 @@ Before you begin this tutorial, perform the following actions: __v: 0 } - This populates the data for the ``author`` field in the data for this - article. Mongoose uses the MongoDB ``$lookup`` method to do this under the - hood. + This populates the data for the ``author`` field with the data for this + article. Mongoose uses the MongoDB ``$lookup`` method to populate the data + automatically. .. step:: Add Middleware - In Mongoose, middleware are functions that run before, and, or during the + In Mongoose, middleware are functions that run before, or during, the execution of asynchronous functions at the schema level. To use middleware in this project, go to the ``Blog.js`` file. Here you @@ -635,13 +645,19 @@ Before you begin this tutorial, perform the following actions: Besides the ``pre()`` middleware function, Mongoose also offers a ``post()`` middleware function. -Resources and Next Steps ------------------------- +Next Steps +---------- You now have a sample project that uses Mongoose to perform CRUD operations on a MongoDB collection. From here, you can choose to build on this project to incorporate :ref:`Mongoose helper methods ` and build more complex queries. +Additional Resources +-------------------- + To learn more about using Mongoose with MongoDB, see the `Mongoose documentation `__. + +To find support or to contribute to the MongoDB community, see the `MongoDB +Developer Community `__ page. \ No newline at end of file From 55005b41cc6acf23849963786a104c630d414f89 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 29 May 2025 08:50:01 -0400 Subject: [PATCH 11/20] formatting --- source/integrations/mongoose-get-started.txt | 37 +++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 9f2607dbb..eb61464b6 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -28,16 +28,6 @@ you to alter and update databases in the future, there aren't rigid schemas. However, Mongoose enforces a semi-rigid schema from the beginning, so you must define a schema and model. -In this tutorial, you will perform the following actions: - -- Set up your environment to use Mongoose -- Connect to MongoDB -- Create a Mongoose schema and model -- Insert, update, find, and delete data -- Project document fields -- Validate your data -- Use multiple schemas and middleware - Schemas ~~~~~~~ @@ -145,8 +135,21 @@ For more information, see the `Model.where() `__ section of the Mongoose API documentation. +Tutorial +-------- + +In this tutorial, you will perform the following actions: + +- Set up your environment to use Mongoose +- Connect to MongoDB +- Create a Mongoose schema and model +- Insert, update, find, and delete data +- Project document fields +- Validate your data +- Use multiple schemas and middleware + Prerequisites -------------- +~~~~~~~~~~~~~ Before you begin this tutorial, perform the following actions: @@ -185,7 +188,7 @@ Before you begin this tutorial, perform the following actions: "type": "module", ... - .. step:: Connect to MongoDB + .. step:: Connect to MongoDB. In the root level of your project, create a file named ``index.js`` and add the following code to the top of the file: @@ -201,7 +204,7 @@ Before you begin this tutorial, perform the following actions: string, see the :atlas:`Connect to Your Cluster ` tutorial in the Atlas documentation. - .. step:: Create a Schema and Model + .. step:: Create a schema and a model. Before you start adding and updating data in MongoDB, you must create a schema and model. @@ -215,7 +218,7 @@ Before you begin this tutorial, perform the following actions: :language: javascript :dedent: - .. step:: Perform CRUD Operations + .. step:: Perform CRUD operations. You now have your first model and schema set up, and you can start inserting data into the database. The following sections show you how to @@ -422,7 +425,7 @@ Before you begin this tutorial, perform the following actions: Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } - .. step:: Validate Your Data + .. step:: Validate your data. The articles inserted in the previous steps do not contain the ``author``, ``dates``, or ``comments`` fields, even though these fields are included @@ -462,7 +465,7 @@ Before you begin this tutorial, perform the following actions: Validators only run on the ``create()`` and ``save()`` methods. - .. step:: Introduce Multiple Schemas + .. step:: Introduce multiple schemas. Now that you have validation on your blog schema, and the ``author`` field is ``required``, you must update ``index.js`` to include the ``author``. To do @@ -593,7 +596,7 @@ Before you begin this tutorial, perform the following actions: article. Mongoose uses the MongoDB ``$lookup`` method to populate the data automatically. - .. step:: Add Middleware + .. step:: Add middleware. In Mongoose, middleware are functions that run before, or during, the execution of asynchronous functions at the schema level. From 61fd0aa72d85e6cb2918ccc16b9d7b7e5fac431e Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Mon, 2 Jun 2025 09:54:14 -0400 Subject: [PATCH 12/20] JS feedback and formatting --- .../mongoose-get-started-blogSchema.js | 14 +- .../mongoose-get-started-multiple-schemas.js | 4 +- source/integrations/mongoose-get-started.txt | 128 +++++++++++------- 3 files changed, 93 insertions(+), 53 deletions(-) diff --git a/source/includes/integrations/mongoose-get-started-blogSchema.js b/source/includes/integrations/mongoose-get-started-blogSchema.js index 893e24574..ab134e5e2 100644 --- a/source/includes/integrations/mongoose-get-started-blogSchema.js +++ b/source/includes/integrations/mongoose-get-started-blogSchema.js @@ -48,4 +48,16 @@ console.log('Deleted One Blog:', blogOne); // Deletes all articles with the slug "awesome-post". const blogMany = await Blog.deleteMany({ slug: "awesome-post" }); console.log('Deleted Many Blogs:', blogMany); -// end-delete-many \ No newline at end of file +// end-delete-many + +// start-validated-insert +// Creates a new blog post and inserts it into database +const article = await Blog.create({ + title: 'Awesome Post!', + slug: 'awesome-post', + published: true, + author: 'A.B. Cee', + content: 'This is the best post ever', + tags: ['featured', 'announcement'], +}); +// end-validated-insert \ No newline at end of file diff --git a/source/includes/integrations/mongoose-get-started-multiple-schemas.js b/source/includes/integrations/mongoose-get-started-multiple-schemas.js index bd532eb56..2986f336b 100644 --- a/source/includes/integrations/mongoose-get-started-multiple-schemas.js +++ b/source/includes/integrations/mongoose-get-started-multiple-schemas.js @@ -6,13 +6,15 @@ import User from './model/User.js'; mongoose.connect(""); -// start-article-with-author +// start-create-user // Create a new user const user = await User.create({ name: 'Jess Garica', email: 'jgarcia@email.com', }); +// end-create-user +// start-article-with-author // Creates a new blog post that references the user as the author const articleAuthor = await Blog.create({ title: 'Awesome Post!', diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index eb61464b6..230d3c437 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -1,8 +1,9 @@ .. _node-mongoose-get-started: +.. original URL: https://www.mongodb.com/developer/languages/javascript/getting-started-with-mongodb-and-mongoose/ -========================= -Get Started with Mongoose -========================= +=================================== +Tutorial: Get Started with Mongoose +=================================== .. facet:: :name: genre @@ -210,7 +211,7 @@ Before you begin this tutorial, perform the following actions: schema and model. With Mongoose, you create a schema model file for each schema that is - needed. First, create the a folder called ``model`` to put all your schema + needed. First, create a folder called ``model`` to put all your schema files in, then create your first schema file called ``Blog.js``. Open this file and add the following code: @@ -224,11 +225,8 @@ Before you begin this tutorial, perform the following actions: inserting data into the database. The following sections show you how to perform CRUD operations using Mongoose. - .. procedure:: - :style: connected - Insert Data - ~~~~~~~~~~~ + ```````````` Go to ``index.js`` and add the following import statement to the top of your file: @@ -282,7 +280,7 @@ Before you begin this tutorial, perform the following actions: insert multiple articles into your database. Update Data - ~~~~~~~~~~~ + ```````````` To update data, you can directly edit the local object with Mongoose. Then, you can use the ``save()`` method to write the update to the @@ -315,9 +313,9 @@ Before you begin this tutorial, perform the following actions: } Find Data - ~~~~~~~~~ + `````````` - To update a specific document, you can use the Mongoose ``findById()`` + To find a specific document, you can use the Mongoose ``findById()`` method to get a document by its ``ObjectId``. Add following code to your ``index.js`` file to find a specific article by @@ -356,9 +354,9 @@ Before you begin this tutorial, perform the following actions: documentation. Specify Document Fields - ~~~~~~~~~~~~~~~~~~~~~~~ + ``````````````````````` - Like with the {+driver-short+}, you can use Mongoose to project only the + You can use Mongoose to project only the fields that you need. The following code specifies to only project the ``title``, ``slug``, and ``content`` fields. @@ -386,7 +384,7 @@ Before you begin this tutorial, perform the following actions: } Delete Data - ~~~~~~~~~~~ + ``````````` Mongoose uses the ``deleteOne()`` and ``deleteMany()`` methods to delete data from a collection. You can specify the field of the document you want @@ -433,22 +431,12 @@ Before you begin this tutorial, perform the following actions: document, you have not defined which fields are required. Any field that is no defined as required can be omitted. - To add data validation and define these requirements, update the schema in - ``Blog.js`` as shown in the following example: - - .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js - :language: javascript - :start-after: start-blogSchema - :end-before: end-blogSchema - :dedent: - In Mongoose, when you include validation on a field, you must pass an object as its value. - .. tip:: + .. note:: - When you use schemas with Mongoose, ``value: String`` is the same as - ``value: {type: String}``. + Validators only run on the ``create()`` and ``save()`` methods. You can use several validation methods with Mongoose. For example, you can set ``required`` to true on any fields that you want to require. You can @@ -461,15 +449,35 @@ Before you begin this tutorial, perform the following actions: arrow function. This field is also specified to be impossible to change later by setting ``immutable`` to ``true``. - .. note:: + To add data validation and define these requirements, update the schema in + ``Blog.js`` as shown in the following example: - Validators only run on the ``create()`` and ``save()`` methods. + .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js + :language: javascript + :start-after: start-blogSchema + :end-before: end-blogSchema + :dedent: + + After adding this validation, your application will crash. Add an + ``author`` field to the ``create()`` call in your ``index.js`` file to + meet the new validation requirement: + + .. literalinclude:: /includes/integrations/mongoose-get-started-blogSchema.js + :start-after: start-validated-insert + :end-before: end-validated-insert + :language: javascript + :emphasize-lines: 5 + :dedent: + + .. tip:: + + When you use schemas with Mongoose, ``value: String`` is the same as + ``value: {type: String}``. .. step:: Introduce multiple schemas. - Now that you have validation on your blog schema, and the ``author`` field is - ``required``, you must update ``index.js`` to include the ``author``. To do - this, you can create a separate schema. + Next, you can add more complexity to your ``author`` field by creating a + another schema, and nesting it in the blog schema. In the ``model`` folder, create a new file named ``User.js``. Add the following code to this file: @@ -478,8 +486,15 @@ Before you begin this tutorial, perform the following actions: :language: javascript :dedent: - To reference this new user model in the blog schema, update the - ``Blog.js`` file to include the following code: + To use your new User model to define the ``author`` field in the blog + schema, update the ``Blog.js`` file with the following changes: + + - Add ``SchemaTypes`` to the list of constructors extracted from the + Mongoose library. + - Change the ``author`` field ``type`` to ``SchemaTypes.ObjectId`` and add + a reference (``ref``) to the ``'User'`` model. + + The following code shows these updates: .. code-block:: javascript @@ -487,30 +502,34 @@ Before you begin this tutorial, perform the following actions: const { Schema, SchemaTypes, model } = mongoose; const blogSchema = new Schema({ - ... - author: { - type: SchemaTypes.ObjectId, - ref: 'User', - required: true, - }, - ..., - comments: [{ - user: { + ... + author: { type: SchemaTypes.ObjectId, ref: 'User', required: true, }, - content: String, - votes: Number - }]; + ..., }); ... + You can also reuse the name User model for the ``comment.user`` field by + changing the ``blogSchema`` definition: + + .. code-block:: javascript - The preceding code sets the ``author`` and ``comments.user`` to - ``SchemaTypes.ObjectId`` and adds a ``ref``, or reference, to the user - model. Be sure to destructure ``SchemaTypes`` from Mongoose at the top of - the file below the import statement. + const blogSchema = new Schema({ + ..., + comments: [{ + user: { + type: SchemaTypes.ObjectId, + ref: 'User', + required: true, + }, + content: String, + votes: Number + }]; + }); + ... To use the new user model in your application, go to the ``index.js`` file. Add the following code to the top of the file to import the user @@ -525,8 +544,15 @@ Before you begin this tutorial, perform the following actions: insert, update, and delete blogs, and to specify fields to project, won't pass the validation and the application will error. - Replace the existing code with the following code to create a new user, - and then create a new article that uses this user as the author, as shown + Create a new user by adding the following ``create()`` call: + + .. literalinclude:: /includes/integrations/mongoose-get-started-multiple-schemas.js + :language: javascript + :start-after: start-create-user + :end-before: end-create-user + + Update the existing ``create()`` call with the following code to create a + new article that uses the new user as the author, as shown in the following code: .. io-code-block:: From 5cc7f32555ad2a6025eb9a2142f0bc7a0be088b8 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Mon, 2 Jun 2025 10:14:43 -0400 Subject: [PATCH 13/20] titles --- source/integrations/mongoose-get-started.txt | 31 ++++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 230d3c437..b23605ea1 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -91,7 +91,7 @@ methods. These methods are not used specifically in this tutorial, but they are helpful to reference when getting started with Mongoose. exists() -```````` +~~~~~~`` The ``exists()`` method returns either ``null`` or the ``ObjectId`` of a document that matches the provided query. The following is an example of matching an article @@ -107,7 +107,7 @@ For more information, see the `Model.exists() Mongoose API documentation. where() -``````` +~~~~~~` The ``where()`` method allows you to chain and build queries. The following is an example of performing a find operation by using ``findOne()`` and the equivalent @@ -149,18 +149,17 @@ In this tutorial, you will perform the following actions: - Validate your data - Use multiple schemas and middleware -Prerequisites -~~~~~~~~~~~~~ +.. procedure:: + :style: connected -Before you begin this tutorial, perform the following actions: + .. step:: Prerequisites -- Set up a MongoDB Atlas account and configure a cluster. - To view instructions, see the :atlas:`Get Started with Atlas - ` guide. -- Install `Node.js `__ {+min-node-version+} or later. + Before you begin this tutorial, perform the following actions: -.. procedure:: - :style: connected + - Set up a MongoDB Atlas account and configure a cluster. To view + instructions, see the :atlas:`Get Started with Atlas ` + guide. + - Install `Node.js `__ {+min-node-version+} or later. .. step:: Set up your environment. @@ -226,7 +225,7 @@ Before you begin this tutorial, perform the following actions: perform CRUD operations using Mongoose. Insert Data - ```````````` + ~~~~~~~~~~~ Go to ``index.js`` and add the following import statement to the top of your file: @@ -280,7 +279,7 @@ Before you begin this tutorial, perform the following actions: insert multiple articles into your database. Update Data - ```````````` + ~~~~~~~~~~~~ To update data, you can directly edit the local object with Mongoose. Then, you can use the ``save()`` method to write the update to the @@ -313,7 +312,7 @@ Before you begin this tutorial, perform the following actions: } Find Data - `````````` + ~~~~~~~~~~ To find a specific document, you can use the Mongoose ``findById()`` method to get a document by its ``ObjectId``. @@ -354,7 +353,7 @@ Before you begin this tutorial, perform the following actions: documentation. Specify Document Fields - ``````````````````````` + ~~~~~~~~~~~~~~~~~~~~~~~ You can use Mongoose to project only the fields that you need. The following code specifies to only project the @@ -384,7 +383,7 @@ Before you begin this tutorial, perform the following actions: } Delete Data - ``````````` + ~~~~~~~~~~~ Mongoose uses the ``deleteOne()`` and ``deleteMany()`` methods to delete data from a collection. You can specify the field of the document you want From c88384fcd708351545e108b386dbabec2496faeb Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Mon, 2 Jun 2025 14:51:20 -0400 Subject: [PATCH 14/20] middleware updates --- .../mongoose-get-started-multiple-schemas.js | 21 ++++-- source/integrations/mongoose-get-started.txt | 67 ++++++++++++------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/source/includes/integrations/mongoose-get-started-multiple-schemas.js b/source/includes/integrations/mongoose-get-started-multiple-schemas.js index 2986f336b..5e13d955b 100644 --- a/source/includes/integrations/mongoose-get-started-multiple-schemas.js +++ b/source/includes/integrations/mongoose-get-started-multiple-schemas.js @@ -34,9 +34,20 @@ console.log('Article Populated:', articlePopulate); // end-populate-author // start-middleware-update -// Middleware to update the updated field before saving -const articleUpdated = await Blog.findById("68262cac638b7ec7ed0a086b").exec(); -articleUpdated.title = "Updated Title"; -await articleUpdated.save(); -console.log('Article Updated:', articleUpdated); +// Uses middleware to update the updated field before saving and updating + +// Create a new article +const articleMiddlewareUpdate = await Blog.create({ + title: 'Another Awesome Post!', + slug: 'Another-Awesome-Post', + author: user._id, + content: 'Here is another awesome post', +}); +console.log('Original Article: ', articleMiddlewareUpdate); +// Wait +await new Promise(resolve => setTimeout(resolve, 1000)); +// Update the article +articleMiddlewareUpdate.content = "Check my updated field" +await articleMiddlewareUpdate.save(); +console.log('Auto-updated Article:', articleMiddlewareUpdate); // end-middleware-update \ No newline at end of file diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index b23605ea1..8a9177c4b 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -152,14 +152,14 @@ In this tutorial, you will perform the following actions: .. procedure:: :style: connected - .. step:: Prerequisites + .. step:: Verify the prerequisites. - Before you begin this tutorial, perform the following actions: + Before you begin this tutorial, ensure you have the following components prepared: - - Set up a MongoDB Atlas account and configure a cluster. To view + - An MongoDB Atlas account with a configured cluster. To view instructions, see the :atlas:`Get Started with Atlas ` guide. - - Install `Node.js `__ {+min-node-version+} or later. + - `Node.js `__ {+min-node-version+} or later. .. step:: Set up your environment. @@ -626,11 +626,11 @@ In this tutorial, you will perform the following actions: In Mongoose, middleware are functions that run before, or during, the execution of asynchronous functions at the schema level. - To use middleware in this project, go to the ``Blog.js`` file. Here you - can set the ``updated`` date field to update every time an article is - saved or updated by using middleware. - - Add the following code to a line below your ``blogSchema`` declaration: + One example of middleware is a function that automatically updates the + ``updated`` field of a ``Blog`` instance before saving or updating. + + To add this middleware function, add the following code to the + ``blogSchema`` declaration in your ``Blog.js`` file: .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js :language: javascript @@ -638,8 +638,9 @@ In this tutorial, you will perform the following actions: :end-before: end-blogSchema-middleware :dedent: - Go to the ``index.js`` file and then add the following code to find an - article, update the title, and then save the updated article: + To see the effect of this function, add the following code to your + ``index.js`` file to find an article, update the title, and then save the + updated article: .. io-code-block:: :copyable: @@ -653,25 +654,41 @@ In this tutorial, you will perform the following actions: :language: console :visible: false - Article Updated: { - _id: new ObjectId('...'), - title: 'Updated Title', - slug: 'awesome-post', + Original Article: { + title: 'Another Awesome Post!', + slug: 'another-awesome-post', published: false, - author: new ObjectId('...'), - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - createdAt: 2025-05-15T18:04:28.590Z, + author: new ObjectId('683df165ce6200f8fafc9c95'), + content: 'Here is another awesome post', + tags: [], + _id: new ObjectId('683df167ce6200f8fafc9ca1'), + createdAt: 2025-06-02T18:45:59.892Z, comments: [], - __v: 0, - updated: 2025-05-15T18:18:30.249Z - } + updated: 2025-06-02T18:45:59.894Z, + __v: 0 + } + Auto-updated Article: { + title: 'Another Awesome Post!', + slug: 'another-awesome-post', + published: false, + author: new ObjectId('683df165ce6200f8fafc9c95'), + content: 'Check my updated field', + tags: [], + _id: new ObjectId('683df167ce6200f8fafc9ca1'), + createdAt: 2025-06-02T18:45:59.892Z, + comments: [], + updated: 2025-06-02T18:46:01.034Z, + __v: 0 + } - When you run the application, the returned article includes an ``updated`` - date. + When you run the application, you can see that the original article has an + ``updated`` value, though one was not specified. You can also see that the + ``updated`` value increase when the article is modified. Besides the ``pre()`` middleware function, Mongoose also offers a - ``post()`` middleware function. + ``post()`` middleware function. For more information about middleware, see + the `Middleware `__ page in + the Mongoose documentation. Next Steps ---------- From f7c3c23c8c31f10df3b990a35adbe446b5180a85 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 5 Jun 2025 12:14:11 -0400 Subject: [PATCH 15/20] JS feedback --- source/integrations/mongoose-get-started.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 8a9177c4b..586adfc47 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -91,7 +91,7 @@ methods. These methods are not used specifically in this tutorial, but they are helpful to reference when getting started with Mongoose. exists() -~~~~~~`` +~~~~~~~~ The ``exists()`` method returns either ``null`` or the ``ObjectId`` of a document that matches the provided query. The following is an example of matching an article @@ -107,7 +107,7 @@ For more information, see the `Model.exists() Mongoose API documentation. where() -~~~~~~` +~~~~~~~ The ``where()`` method allows you to chain and build queries. The following is an example of performing a find operation by using ``findOne()`` and the equivalent @@ -511,7 +511,7 @@ In this tutorial, you will perform the following actions: }); ... - You can also reuse the name User model for the ``comment.user`` field by + You can reuse the same ``User`` model for the ``comment.user`` field by changing the ``blogSchema`` definition: .. code-block:: javascript From 9e9eb2de9cc8c6da809076e87d2b81a6a5337565 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 12 Jun 2025 10:44:06 -0400 Subject: [PATCH 16/20] VK feedback --- .../mongoose-blogSchema-validate.js | 10 +- .../integrations/mongoose-blogSchema.js | 4 +- .../integrations/mongoose-middleware.js | 22 ++ ...chemas.js => mongoose-multiple-schemas.js} | 0 .../integrations/mongoose-schema-example.js | 4 +- .../mongoose-userSchema-validate.js | 39 +++ source/integrations/mongoose-get-started.txt | 311 ++++++++++-------- 7 files changed, 233 insertions(+), 157 deletions(-) create mode 100644 source/includes/integrations/mongoose-middleware.js rename source/includes/integrations/{mongoose-get-started-multiple-schemas.js => mongoose-multiple-schemas.js} (100%) create mode 100644 source/includes/integrations/mongoose-userSchema-validate.js diff --git a/source/includes/integrations/mongoose-blogSchema-validate.js b/source/includes/integrations/mongoose-blogSchema-validate.js index 8aa5e6228..4c343363c 100644 --- a/source/includes/integrations/mongoose-blogSchema-validate.js +++ b/source/includes/integrations/mongoose-blogSchema-validate.js @@ -10,7 +10,7 @@ const blogSchema = new Schema({ slug: { type: String, required: true, - lowercase: true, + minLength: 4, }, published: { type: Boolean, @@ -22,17 +22,13 @@ const blogSchema = new Schema({ }, content: String, tags: [String], - createdAt: { - type: Date, - default: () => Date.now(), - immutable: true, - }, - updated: Date, comments: [{ user: String, content: String, votes: Number }] +}, { + timestamps: true }); // end-blogSchema diff --git a/source/includes/integrations/mongoose-blogSchema.js b/source/includes/integrations/mongoose-blogSchema.js index e19cf23fc..37a8e6a15 100644 --- a/source/includes/integrations/mongoose-blogSchema.js +++ b/source/includes/integrations/mongoose-blogSchema.js @@ -8,13 +8,13 @@ const blogSchema = new Schema({ author: String, content: String, tags: [String], - createdAt: Date, - updated: Date, comments: [{ user: String, content: String, votes: Number }] +}, { + timestamps: true }); const Blog = model('Blog', blogSchema); diff --git a/source/includes/integrations/mongoose-middleware.js b/source/includes/integrations/mongoose-middleware.js new file mode 100644 index 000000000..ef3c31818 --- /dev/null +++ b/source/includes/integrations/mongoose-middleware.js @@ -0,0 +1,22 @@ +import mongoose from 'mongoose'; +import User from './model/User.js'; +// start-user-import +import User from './model/User.js'; +// end-user-import + +mongoose.connect(""); + +// start-create-user-bad-email +const user = await User.create({ + name: 'Jess Garica', + email: 'jgarciaemail.com', +}); +// end-create-user-bad-email + +// start-create-user-ok-email +const user = await User.create({ + name: 'Jess Garica', + email: 'jgarcia@email.com', +}); +// end-create-user-ok-email + diff --git a/source/includes/integrations/mongoose-get-started-multiple-schemas.js b/source/includes/integrations/mongoose-multiple-schemas.js similarity index 100% rename from source/includes/integrations/mongoose-get-started-multiple-schemas.js rename to source/includes/integrations/mongoose-multiple-schemas.js diff --git a/source/includes/integrations/mongoose-schema-example.js b/source/includes/integrations/mongoose-schema-example.js index d519251ae..30ade39a2 100644 --- a/source/includes/integrations/mongoose-schema-example.js +++ b/source/includes/integrations/mongoose-schema-example.js @@ -8,13 +8,13 @@ const blog = new Schema({ author: String, content: String, tags: [String], - createdAt: Date, - updated: Date, comments: [{ user: String, content: String, votes: Number }] +}, { + timestamps: true }); // end-schema-example const Blog = model('Blog', blog); diff --git a/source/includes/integrations/mongoose-userSchema-validate.js b/source/includes/integrations/mongoose-userSchema-validate.js new file mode 100644 index 000000000..2b1747a69 --- /dev/null +++ b/source/includes/integrations/mongoose-userSchema-validate.js @@ -0,0 +1,39 @@ +import mongoose from 'mongoose'; +// start-validate-import +import validator from 'validator'; +// end-validate-import +const {Schema, model} = mongoose; + +const userSchema = new Schema({ + name: { + type: String, + required: true, + }, + email: { + type: String, + minLength: 10, + required: true, + lowercase: true + }, +}); + +// start-middleware-definition +userSchema.pre('save', function (next) { + const user = this; + + // Normalize email + if (user.email) { + user.email = user.email.trim().toLowerCase(); + } + + // Validate email format + if (!validator.isEmail(user.email)) { + return next(new Error('Invalid email format')); + } + + next(); +}); +// end-middleware-definition + +const User = model('User', userSchema); +export default User; diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 586adfc47..1f725ebb1 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -54,7 +54,9 @@ following types are permitted: - Mixed - ObjectId - Array +- Int32 - Decimal128 +- Double - Map Models @@ -82,60 +84,6 @@ MongoDB. .. _node-mongoose-get-started-helper-methods: -Helper Methods -~~~~~~~~~~~~~~ - -Mongoose includes several helper methods that are abstracted from regular -MongoDB methods. In this section, you can find examples of some of these -methods. These methods are not used specifically in this tutorial, but they are -helpful to reference when getting started with Mongoose. - -exists() -~~~~~~~~ - -The ``exists()`` method returns either ``null`` or the ``ObjectId`` of a document that -matches the provided query. The following is an example of matching an article -based on the ``author`` field: - -.. code-block:: javascript - - const blog = await Blog.exists({ author: 'Jess Garcia' }); - console.log(blog); - -For more information, see the `Model.exists() -`__ section of the -Mongoose API documentation. - -where() -~~~~~~~ - -The ``where()`` method allows you to chain and build queries. The following is -an example of performing a find operation by using ``findOne()`` and the equivalent -approach by using the ``where()`` method: - -.. code-block:: javascript - - const blogFind = await Blog.findOne({ author: "Jess Garcia" }); - console.log(blogFind); - - const blogWhere = await Blog.where("author").equals("Jess Garcia"); - console.log(blogWhere); - -You can use either method to perform find operations. You can also chain -multiple ``where()`` methods to build increasingly complex queries. - -To include projection when using the ``where()`` method, chain the ``select()`` method -after your query, as shown in the following example: - -.. code-block:: javascript - - const blog = await Blog.where("author").equals("Jess Garcia").select("title author"); - console.log(blog); - -For more information, see the `Model.where() -`__ section of the -Mongoose API documentation. - Tutorial -------- @@ -152,7 +100,7 @@ In this tutorial, you will perform the following actions: .. procedure:: :style: connected - .. step:: Verify the prerequisites. + .. step:: Verify the prerequisites Before you begin this tutorial, ensure you have the following components prepared: @@ -161,7 +109,7 @@ In this tutorial, you will perform the following actions: guide. - `Node.js `__ {+min-node-version+} or later. - .. step:: Set up your environment. + .. step:: Set up your environment This tutorial uses `nodemon `__ to run the code locally. Run the following commands in your terminal to @@ -187,8 +135,16 @@ In this tutorial, you will perform the following actions: }, "type": "module", ... + + Start your application with ``nodemon`` by running the following command: + + .. code-block:: json + + npm run dev + + Every time you save a code change, your application will run again. - .. step:: Connect to MongoDB. + .. step:: Connect to MongoDB In the root level of your project, create a file named ``index.js`` and add the following code to the top of the file: @@ -204,7 +160,7 @@ In this tutorial, you will perform the following actions: string, see the :atlas:`Connect to Your Cluster ` tutorial in the Atlas documentation. - .. step:: Create a schema and a model. + .. step:: Create a schema and a model Before you start adding and updating data in MongoDB, you must create a schema and model. @@ -217,8 +173,14 @@ In this tutorial, you will perform the following actions: .. literalinclude:: /includes/integrations/mongoose-blogSchema.js :language: javascript :dedent: + + This schema enables a ``timestamps`` option, which adds Mongoose-manged + ``createdAt`` and ``updatedAt`` fields to the schema that are updated + automatically. For more information, see the `Timestamps + `__ page in the Mongoose + documentation. - .. step:: Perform CRUD operations. + .. step:: Perform CRUD operations You now have your first model and schema set up, and you can start inserting data into the database. The following sections show you how to @@ -315,11 +277,10 @@ In this tutorial, you will perform the following actions: ~~~~~~~~~~ To find a specific document, you can use the Mongoose ``findById()`` - method to get a document by its ``ObjectId``. + method to query for a document by specifying its ``_id``. Add following code to your ``index.js`` file to find a specific article by - its ``ObjectId``, replacing the ```` placeholder with the - ``ObjectId`` value for the document that you inserted previously: + its ``_id``: .. io-code-block:: :copyable: @@ -346,10 +307,11 @@ In this tutorial, you will perform the following actions: .. note:: - The Mongoose ``exec()`` function is an option of the ``findById()`` - method that returns a promise. To learn more about working with - promises and Mongoose, see the `Promises guide - `__ in the Mongoose + By default, Mongoose queries return thenables, which are objects with + some of the properties of a JavaScript Promise. You can append the + ``exec()`` method to a query to receive a true JavaScript Promise. To + learn more about working with promises and Mongoose, see the `Promises + guide `__ in the Mongoose documentation. Specify Document Fields @@ -422,31 +384,32 @@ In this tutorial, you will perform the following actions: Deleted Many Blogs: { acknowledged: true, deletedCount: 4 } - .. step:: Validate your data. + .. step:: Validate your data The articles inserted in the previous steps do not contain the ``author``, ``dates``, or ``comments`` fields, even though these fields are included in the schema. This is because although you defined the structure of your document, you have not defined which fields are required. Any field that - is no defined as required can be omitted. + is not defined as required can be omitted. In Mongoose, when you include validation on a field, you must pass an object as its value. .. note:: - Validators only run on the ``create()`` and ``save()`` methods. + Validators automatically run on the ``create()`` and ``save()``methods. + You specify them to run them on update methods, such as ``update()`` + and ``updateOne()`` by setting the ``runValidators`` option to + ``true``. For more information about validators, see the `Validation + `__ page in the Mongoose + documentation. You can use several validation methods with Mongoose. For example, you can set ``required`` to true on any fields that you want to require. You can also validate the type and the formatting. In the preceding code, the - ``slug`` field is defined as a ``string`` that is always in ``lowercase``. - This validation takes the slug input and converts it to lowercase before - saving the document to the database. - - For the ``createdAt`` date field, you can set the default by using an - arrow function. This field is also specified to be impossible to change - later by setting ``immutable`` to ``true``. + ``slug`` field is defined as a ``string`` with a ``minLength`` of ``4``. + This means that providing a ``slug`` with fewer than 4 characters will + result in a ``ValidationError``. To add data validation and define these requirements, update the schema in ``Blog.js`` as shown in the following example: @@ -472,8 +435,25 @@ In this tutorial, you will perform the following actions: When you use schemas with Mongoose, ``value: String`` is the same as ``value: {type: String}``. + + For more information, see the `Validation + `__ page in the Mongoose + documentation. + + .. tip:: Mongoose Custom Setters - .. step:: Introduce multiple schemas. + Mongoose also provides three custom setter options that modify your data + when it is saved, and can be implemented in the same was as validators: + + - lowercase + - uppercase + - trim + + For more information, see the `SchemaStringOptions + ` + page in the Mongoose API documentation. + + .. step:: Introduce multiple schemas Next, you can add more complexity to your ``author`` field by creating a another schema, and nesting it in the blog schema. @@ -488,7 +468,7 @@ In this tutorial, you will perform the following actions: To use your new User model to define the ``author`` field in the blog schema, update the ``Blog.js`` file with the following changes: - - Add ``SchemaTypes`` to the list of constructors extracted from the + - Add ``SchemaTypes`` to the list of properties extracted from the Mongoose library. - Change the ``author`` field ``type`` to ``SchemaTypes.ObjectId`` and add a reference (``ref``) to the ``'User'`` model. @@ -497,18 +477,14 @@ In this tutorial, you will perform the following actions: .. code-block:: javascript - import mongoose from 'mongoose'; const { Schema, SchemaTypes, model } = mongoose; - - const blogSchema = new Schema({ - ... + + ... // Inside Schema block: author: { type: SchemaTypes.ObjectId, ref: 'User', required: true, }, - ..., - }); ... You can reuse the same ``User`` model for the ``comment.user`` field by @@ -516,25 +492,20 @@ In this tutorial, you will perform the following actions: .. code-block:: javascript - const blogSchema = new Schema({ - ..., + ... // Inside Schema block: comments: [{ user: { type: SchemaTypes.ObjectId, ref: 'User', required: true, }, - content: String, - votes: Number - }]; - }); ... To use the new user model in your application, go to the ``index.js`` file. Add the following code to the top of the file to import the user model: - .. literalinclude:: /includes/integrations/mongoose-get-started-multiple-schemas.js + .. literalinclude:: /includes/integrations/mongoose-multiple-schemas.js :language: javascript :start-after: start-user-import :end-before: end-user-import @@ -545,7 +516,7 @@ In this tutorial, you will perform the following actions: Create a new user by adding the following ``create()`` call: - .. literalinclude:: /includes/integrations/mongoose-get-started-multiple-schemas.js + .. literalinclude:: /includes/integrations/mongoose-multiple-schemas.js :language: javascript :start-after: start-create-user :end-before: end-create-user @@ -557,7 +528,7 @@ In this tutorial, you will perform the following actions: .. io-code-block:: :copyable: - .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + .. input:: /includes/integrations/mongoose-multiple-schemas.js :language: javascript :start-after: start-article-with-author :end-before: end-article-with-author @@ -584,13 +555,16 @@ In this tutorial, you will perform the following actions: field and sets its value to the ``user._id``. To add the values of the ``name`` and ``email`` fields to the ``author`` - field for the article, you can use the Mongoose ``populate()`` method. Add - the following code to ``index.js`` to populate this data: + field for the article, you can append the Mongoose ``populate()`` method + to your Blog query. The ``populate()`` method will perform a second query + for the User document referenced by ``user._id``. + + Add the following code to ``index.js`` to populate this data: .. io-code-block:: :copyable: - .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + .. input:: /includes/integrations/mongoose-multiple-schemas.js :language: javascript :start-after: start-populate-author :end-before: end-populate-author @@ -617,74 +591,60 @@ In this tutorial, you will perform the following actions: __v: 0 } - This populates the data for the ``author`` field with the data for this - article. Mongoose uses the MongoDB ``$lookup`` method to populate the data - automatically. + For more information, see the `Document.populate() + `__ + page of the Mongoose API documentation. - .. step:: Add middleware. + .. step:: Add middleware In Mongoose, middleware are functions that run before, or during, the execution of asynchronous functions at the schema level. - One example of middleware is a function that automatically updates the - ``updated`` field of a ``Blog`` instance before saving or updating. + One example of middleware is a function that validates the + ``email`` field of a ``User`` instance before saving or updating. + + This example uses the ``validator`` package. You can install the + ``validator`` package by running the following command: + + .. code-block:: bash + + npm install validator To add this middleware function, add the following code to the - ``blogSchema`` declaration in your ``Blog.js`` file: + ``userSchema`` declaration in your ``User.js`` file: - .. literalinclude:: /includes/integrations/mongoose-blogSchema-validate.js + .. literalinclude:: /includes/integrations/mongoose-userSchema-validate.js + :language: javascript + :start-after: start-validate-import + :end-before: end-validate-import + :dedent: + + .. literalinclude:: /includes/integrations/mongoose-userSchema-validate.js :language: javascript - :start-after: start-blogSchema-middleware - :end-before: end-blogSchema-middleware + :start-after: start-middleware-definition + :end-before: end-middleware-definition :dedent: - To see the effect of this function, add the following code to your - ``index.js`` file to find an article, update the title, and then save the - updated article: + To see the effect of this function, modify the ``user.email`` field in + your ``index.js`` file to make it an invalid email address: .. io-code-block:: :copyable: - .. input:: /includes/integrations/mongoose-get-started-multiple-schemas.js + .. input:: /includes/integrations/mongoose-middleware.js :language: javascript - :start-after: start-middleware-update - :end-before: end-middleware-update + :start-after: start-create-user-bad-email + :end-before: end-create-user-bad-email + :emphasize-lines: 3 .. output:: :language: console :visible: false - - Original Article: { - title: 'Another Awesome Post!', - slug: 'another-awesome-post', - published: false, - author: new ObjectId('683df165ce6200f8fafc9c95'), - content: 'Here is another awesome post', - tags: [], - _id: new ObjectId('683df167ce6200f8fafc9ca1'), - createdAt: 2025-06-02T18:45:59.892Z, - comments: [], - updated: 2025-06-02T18:45:59.894Z, - __v: 0 - } - Auto-updated Article: { - title: 'Another Awesome Post!', - slug: 'another-awesome-post', - published: false, - author: new ObjectId('683df165ce6200f8fafc9c95'), - content: 'Check my updated field', - tags: [], - _id: new ObjectId('683df167ce6200f8fafc9ca1'), - createdAt: 2025-06-02T18:45:59.892Z, - comments: [], - updated: 2025-06-02T18:46:01.034Z, - __v: 0 - } - - When you run the application, you can see that the original article has an - ``updated`` value, though one was not specified. You can also see that the - ``updated`` value increase when the article is modified. + Error: Invalid email format + + If you correct the email address, you can see that the error is not thrown. + Besides the ``pre()`` middleware function, Mongoose also offers a ``post()`` middleware function. For more information about middleware, see the `Middleware `__ page in @@ -694,9 +654,68 @@ Next Steps ---------- You now have a sample project that uses Mongoose to perform CRUD operations on a -MongoDB collection. From here, you can choose to build on this project to -incorporate :ref:`Mongoose helper methods -` and build more complex queries. +MongoDB collection. From here, you can choose to build on this project with more +complex queries or document validation. + +Helper Methods +~~~~~~~~~~~~~~ + +Mongoose includes several helper methods that are abstracted from regular +MongoDB methods. In this section, you can find examples of some of these +methods. These methods are not used specifically in this tutorial, but they are +helpful to reference when getting started with Mongoose. + +exists() +~~~~~~~~ + +The ``exists()`` method returns either ``null`` or the first document that +matches the provided query. The following is an example of matching an article +based on the ``author`` field: + +.. code-block:: javascript + + const blog = await Blog.exists({ author: 'Jess Garcia' }); + console.log(blog); + +For more information, see the `Model.exists() +`__ section of the +Mongoose API documentation. + +where() +~~~~~~~ + +The ``where()`` method allows you to chain and build complex queries. + +The following is an example of performing a find operation by using +``findOne()`` with a plain query object and the equivalent +query with the ``where()`` method: + +.. code-block:: javascript + + const blogFind = await Blog.findOne({ author: "Jess Garcia" }); + console.log(blogFind); + + const blogWhere = await Blog.where("author").equals("Jess Garcia"); + console.log(blogWhere); + +Generally, the ``where()`` method is used for complex queries involving dynamic +query building or multiple comparators, or when using this method improves +readability. However, there is no performance difference between using the +``where()`` or a plain object query. + +To include projection when using the ``where()`` method, chain the ``select()`` method +after your query, as shown in the following example: + +.. code-block:: javascript + + const blog = await Blog.where("author").equals("Jess Garcia").select("title author"); + console.log(blog); + +For more information, see the following sections of the Mongoose API +documentation: + +- `Model.where() `__ +- `Query.select()`__ Additional Resources -------------------- From 618d31c8a9245c1f52b0e69a78b5b9a8be9c4fc3 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 12 Jun 2025 11:37:51 -0400 Subject: [PATCH 17/20] move custom setters section --- source/integrations/mongoose-get-started.txt | 89 +++++++++----------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 1f725ebb1..651344ec8 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -140,9 +140,11 @@ In this tutorial, you will perform the following actions: .. code-block:: json - npm run dev + npm run dev - Every time you save a code change, your application will run again. + .. note:: + + When you use nodemon, the code runs every time you save a file. .. step:: Connect to MongoDB @@ -210,36 +212,6 @@ In this tutorial, you will perform the following actions: The returned document logs to the console, including its ``_id``. Take note of this ``_id`` for use in future steps. - To run the code, use the following command in your terminal: - - .. io-code-block:: - :copyable: - - .. input:: - :language: bash - - npm run dev - - .. output:: - :language: console - :visible: false - - Created article: { - title: 'Awesome Post!', - slug: 'awesome-post', - published: true, - content: 'This is the best post ever', - tags: [ 'featured', 'announcement' ], - _id: new ObjectId('...'), - comments: [], - __v: 0 - } - - .. note:: - - When you use nodemon, the code runs every time you save a file. Saving will - insert multiple articles into your database. - Update Data ~~~~~~~~~~~~ @@ -310,7 +282,7 @@ In this tutorial, you will perform the following actions: By default, Mongoose queries return thenables, which are objects with some of the properties of a JavaScript Promise. You can append the ``exec()`` method to a query to receive a true JavaScript Promise. To - learn more about working with promises and Mongoose, see the `Promises + learn more about working with promises in Mongoose, see the `Promises guide `__ in the Mongoose documentation. @@ -397,8 +369,8 @@ In this tutorial, you will perform the following actions: .. note:: - Validators automatically run on the ``create()`` and ``save()``methods. - You specify them to run them on update methods, such as ``update()`` + Validators automatically run on the ``create()`` and ``save()`` methods. + You can specify them to run them on update methods, such as ``update()`` and ``updateOne()`` by setting the ``runValidators`` option to ``true``. For more information about validators, see the `Validation `__ page in the Mongoose @@ -406,7 +378,7 @@ In this tutorial, you will perform the following actions: You can use several validation methods with Mongoose. For example, you can set ``required`` to true on any fields that you want to require. You can - also validate the type and the formatting. In the preceding code, the + also validate the type and the formatting. In the following code, the ``slug`` field is defined as a ``string`` with a ``minLength`` of ``4``. This means that providing a ``slug`` with fewer than 4 characters will result in a ``ValidationError``. @@ -428,7 +400,7 @@ In this tutorial, you will perform the following actions: :start-after: start-validated-insert :end-before: end-validated-insert :language: javascript - :emphasize-lines: 5 + :emphasize-lines: 6 :dedent: .. tip:: @@ -439,19 +411,6 @@ In this tutorial, you will perform the following actions: For more information, see the `Validation `__ page in the Mongoose documentation. - - .. tip:: Mongoose Custom Setters - - Mongoose also provides three custom setter options that modify your data - when it is saved, and can be implemented in the same was as validators: - - - lowercase - - uppercase - - trim - - For more information, see the `SchemaStringOptions - ` - page in the Mongoose API documentation. .. step:: Introduce multiple schemas @@ -657,6 +616,36 @@ You now have a sample project that uses Mongoose to perform CRUD operations on a MongoDB collection. From here, you can choose to build on this project with more complex queries or document validation. +Mongoose Custom Setters +~~~~~~~~~~~~~~~~~~~~~~~ + +Custom setters modify your data when it is saved, and can be implemented similar +to validators. Mongoose provides the following custom setters: + +- ``lowercase`` +- ``uppercase`` +- ``trim`` + +The following example lowercases the characters in the ``blog.slug`` field: + +.. code-block:: javascript + :emphasize-lines: 7 + + const blogSchema = new Schema({ + ... + slug: { + type: String, + required: true, + minLength: 4, + lowercase: true, + }, + ... + }); + +For more information, see the `SchemaStringOptions +`__ +page in the Mongoose API documentation. + Helper Methods ~~~~~~~~~~~~~~ From b1dd10b0f5e1f04f15021b329d9102bc0230225a Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 12 Jun 2025 11:40:44 -0400 Subject: [PATCH 18/20] typos --- source/integrations/mongoose-get-started.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 651344ec8..eb0cb5a92 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -689,8 +689,8 @@ query with the ``where()`` method: Generally, the ``where()`` method is used for complex queries involving dynamic query building or multiple comparators, or when using this method improves -readability. However, there is no performance difference between using the -``where()`` or a plain object query. +readability. There is no performance difference between using the +``where()`` method or a plain object query. To include projection when using the ``where()`` method, chain the ``select()`` method after your query, as shown in the following example: @@ -704,7 +704,7 @@ For more information, see the following sections of the Mongoose API documentation: - `Model.where() `__ -- `Query.select()`__ +- `Query.select() `__ Additional Resources -------------------- From 95801f97e89b9aa0a6286ea08534d7968a08bd57 Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 12 Jun 2025 12:02:17 -0400 Subject: [PATCH 19/20] intro line --- source/integrations/mongoose-get-started.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index eb0cb5a92..4c7810833 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -614,7 +614,8 @@ Next Steps You now have a sample project that uses Mongoose to perform CRUD operations on a MongoDB collection. From here, you can choose to build on this project with more -complex queries or document validation. +complex queries or document validation. The following sections includes some +examples of Mongoose features that you might use to in your application. Mongoose Custom Setters ~~~~~~~~~~~~~~~~~~~~~~~ From 19e4b105a91591f05fb39eff9cfa4e69941906fd Mon Sep 17 00:00:00 2001 From: Rachel Mackintosh Date: Thu, 12 Jun 2025 12:53:28 -0400 Subject: [PATCH 20/20] vale --- source/includes/integrations/mongoose-middleware.js | 4 ++-- source/integrations/mongoose-get-started.txt | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/includes/integrations/mongoose-middleware.js b/source/includes/integrations/mongoose-middleware.js index ef3c31818..04e177888 100644 --- a/source/includes/integrations/mongoose-middleware.js +++ b/source/includes/integrations/mongoose-middleware.js @@ -6,12 +6,12 @@ import User from './model/User.js'; mongoose.connect(""); -// start-create-user-bad-email +// start-create-user-improper-email const user = await User.create({ name: 'Jess Garica', email: 'jgarciaemail.com', }); -// end-create-user-bad-email +// end-create-user-improper-email // start-create-user-ok-email const user = await User.create({ diff --git a/source/integrations/mongoose-get-started.txt b/source/integrations/mongoose-get-started.txt index 4c7810833..80658cbf3 100644 --- a/source/integrations/mongoose-get-started.txt +++ b/source/integrations/mongoose-get-started.txt @@ -280,7 +280,7 @@ In this tutorial, you will perform the following actions: .. note:: By default, Mongoose queries return thenables, which are objects with - some of the properties of a JavaScript Promise. You can append the + some properties of a JavaScript Promise. You can append the ``exec()`` method to a query to receive a true JavaScript Promise. To learn more about working with promises in Mongoose, see the `Promises guide `__ in the Mongoose @@ -592,8 +592,8 @@ In this tutorial, you will perform the following actions: .. input:: /includes/integrations/mongoose-middleware.js :language: javascript - :start-after: start-create-user-bad-email - :end-before: end-create-user-bad-email + :start-after: start-create-user-improper-email + :end-before: end-create-user-improper-email :emphasize-lines: 3 .. output::