MongoDB Python Developer Path

Ace your homework & exams now with Quizwiz!

Static Indexing

The fields being queried are always the same.

Finding Documents by Using Comparison Operators

$gt (greater than) Returns documents where the field contains a value greater than the specified value. Syntax: db.sales.find({"items.price":{$gt:50}}) $lt (less than) Returns documents where the field contains a value less than the specified value. Syntax: db.sales.find({"items.price":{$lt:50}}) $lte (less than or equal to) Returns documents where the field contains a value less than or equal to the specified value. Syntax: db.sales.find({"items.price":{$lte:50}}) $gte (greater than or equal to) Returns documents where the field contains a value greater than or equal to the specified value. Syntax: db.sales.find({"items.price":{$gte:50}})

$in Operator

$in The $in operator allows us to select all documents that have a field value equal to any of the values specified in the array. Syntax: db.<collection>.find({<field>:{$in: [<value>,<value>,...]}}) Example: db.zips.find({city:{$in:["PHOENIX","CHICAGO"]}})

Using $match and $group Stages in a MongoDB Aggregation Pipeline

$match - Filter for documents matching criteria. The $match stage filters for documents that match specified conditions. Syntax: { $match: { "field_name": "value" } } Note: -> Place as early as possible in the pipeline so it can use indexes ->Reduces the number of documents. ->Lessens processing required. $group - Create a single document for each distinct value. Groups documents by a group key. Output is one document for each unique value of the group key. The $group stage groups documents by a group key. Syntax: { $group: { _id: <expression>, // Group key <field>: { <accumulator> : <expression> } } }

Using the $out Stage in a MongoDB Aggregation Pipeline

$out ->. Creates a new collection that contains the documents in this stage of the aggregation pipeline. ->Writes the documents that are returned by an aggregation pipeline into a collection. -> Must be the last stage. -> Creates a new collection if it does not already exist. -> If collection exists, $out replaces the existing collection with new data. Syntax The $out stage has the following syntax: Starting in MongoDB 4.4, $out can take a document to specify the output database as well as the output collection: { $out: { db: "<output-db>", coll: "<output-collection>" } } Description db The output database name. For a replica set or a standalone, if the output database does not exist, $out also creates the database. For a sharded cluster, the specified output database must already exist. coll The output collection name. $out can take a string to specify only the output collection (i.e. output to a collection in the same database): { $out: "<output-collection>" } // Output collection is in the same database

What are indexes?

-Indexes are ordered data structure that store some fields from a collection to allow faster data retrieval and reduce computation. ->Indexes improve query performance at the cost of write performance. ->Special data structures. ->Store small portion of the data. ->Ordered and easy to search efficiently. ->Point to the document identity.

Using $project, $count, and $set Stages in a MongoDB Aggregation Pipeline

$project ->Determines output shape. ->Projection similar to find() operations. -> This should be the last stage to format the output. The $project stage specifies the fields of the output documents. 1 means that the field should be included, and 0 means that the field should be suppressed. The field can also be assigned a new value. Syntax: { $project: { state:1, zip:1, population:"$pop", _id:0 } } } $set ->Adds or modifies fields in the pipeline. ->Useful when we want to change existing fields in the pipeline or add new ones to be used in upcoming pipeline stages. The $set stage creates new fields or changes the value of existing fields and then outputs the documents with the new fields. Syntax: { $set: { place: { $concat:["$city",",","$state"] }, pop:10000 } } $count -> Counts documents in the pipeline. -> Returns the total document count. The $count stage creates a new document, with the number of documents at that stage in the aggregation pipeline assigned to the specified field name. Syntax: { $count: "total_zips" }

Grouping Search Results by Using Facets

$searchMeta and $facet $searchMeta is an aggregation stage for Atlas Search where the metadata related to the search is shown. This means that if our search results are broken into buckets, using $facet, we can see that in the $searchMeta stage, because those buckets are information about how the search results are formatted. $searchMeta: { "facet": { "operator": { "text": { "query": ["Northern Cardinal"], "path": "common_name" } }, "facets": { "sightingWeekFacet": { "type": "date", "path": "sighting", "boundaries": [ISODate("2022-01-01"), ISODate("2022-01-08"), ISODate("2022-01-15"), ISODate("2022-01-22")], "default" : "other" } } } } "facet" is an operator within $searchMeta. "operator" refers to the search operator - the query itself. "facets" operator is where we put the definition of the buckets for the facets.

Using $sort and $limit Stages in a MongoDB Aggregation Pipeline

$sort - Sorts all input documents and passes them through pipeline in sorted order. 1: Ascending order (smaller to bigger) -1: Descending order (bigger to smaller) The $sort stage sorts all input documents and returns them to the pipeline in sorted order. We use 1 to represent ascending order, and -1 to represent descending order. Syntax: { $sort: { "field_name": 1 } } $limit - Limits the number of documents that are passed on the next aggregation stage. The $limit stage returns only a specified number of records. Syntax: { $limit: { 5 } }

Consider a banking database that stores information on customers, such as their contact information, account information, and all account activity information. A one-to-many relationship exists between the customer and their transactions. Which of the following are valid ways to represent this one-to-many relationship between the customer and their transactions? (Select all that apply.)

-> Create two collections: one collection for the customers' identifying information and one collection for the transactions. In the transactions collection, each document contains a customer's transactions and a field to reference the customer's information document. ->Embed the transactions for each customer as an array of subdocuments in the corresponding customer document

Deleting MongoDB Indexes

-> Deleting an index can affect the query performance. -> We use dropIndex() to delete one index. -> We use dropIndexes() to delete more than one index. -> We use hideIndex() to hide an index. -> Delete an index in the Atlas UI with the Drop Index option. ->Indexes improve performance ->Indexes have a write cost ->Too many indexes in a collection can affect system performance. ->Delete unused or redundant indexes. ->Make sure the index is not being used Deleting an index that's the only index supporting a query will affect the performance of the query. ->Recreating an index takes time and resources. ->Hide the index before deleting it.

Which of the following are benefits of a proper data model?

->A proper data model makes it easier to manage your data. ->A proper data model makes queries more efficient. ->A proper data model uses less memory and CPU. ->A proper data model reduces costs.

Compound Indexes

->An index that contains references to multiple fields within a document ->The order of the fields in a compound the index matters. -> Index on multiple fields. ->Follow this order: Equality, Sort, Range ->The sort order if the field values in the index matters. -> Can be a multikey index if it includes an array field. ->Maximum of one array field per index. ->Support queries that match on the prefix of the index fields.

Multikey Indexes

->Any index where one of the indexed fields contains an array. -> The array can hold nested objects or other field types. ->Index on an array field. ->In a compound index, only one field can be an array per index. ->Can be single field or compound index. ->One array field per index.

Data Modeling

->Data modeling is the process of defining how data is stored. ->Data modeling is the process of defining the relationships that exist among different entities in your data.

Types of Data Relationships:

->Data that is accessed together should be stored together. ->Modeling one-to-one, one-to-many, and many-to-many relationships is easy in MongoDB. ->One-to-One : A relationship where a data entity in one set is connected to exactly one data entity in another set. ->One-to-Many: A relationship where a data entity in one set is connected to any number of data entities in another set. ->Many-to-Many: A relationship where any number of data entities in one set are connected to any number of data entities in another set. -> The two primary ways of modeling data relationships in MongoDB are embedding and referencing.t, embedding it, or linking it with a reference. -> We can represent relationships in many ways: by inserting data into the documen

A good data model can:

->Data that is accessed together should be stored together. ->MongoDB implements a flexible document data model. ->Embedded document model enables us to build complex relationship among data. ->You can normalize your data by using database references. ->The key principle here is How your application will use the data rather than how it's stored in the database.

Which of the following statements are true about multi-document transactions in MongoDB? (Select all that apply.)

->Database operations that affect more than one document, like .updateMany(), are not inherently atomic in MongoDB and must be completed by using a multi-document transaction in order to have ACID properties. ->Multi-document transactions should be treated as a precise tool that is used only in certain scenarios. ->Using a multi-document transaction with a MongoDB database ensures that the database will be in a consistent state after running a set of operations on multiple documents.

Sort

->Determines the order of results. ->Index sort eliminates the need for in-memory sorts. ->Sort order is important if query results are sorted by more than 1 field and they mix sort orders.

What is the minimum Atlas Cluster tier that you must have to use the Performance Advisor tool?

->M10 The Performance Advisor tool is available in M10+ cluster tiers.

Most Common index type in mongoDB:

->Single Field index A single field index is an index on a single field of a document. MongoDB creates a single field index on the _id field by default, but additional indexes may be needed for other fields as well. A single field index can also be a multikey index if it operates on an array field ->Compound Index Compound index: MongoDB supports compound indexes, where a single index structure holds references to multiple fields within a collection's documents. A compound index is created by specifying the fields that the index should reference, followed by the order in which the fields should be sorted. The order of the fields in the index is important because it determines the order in which the documents are returned when querying the collection. A compound index can also be a multikey index if one of the fields is an array. ->Multikey indexes operate on an array field Multikey index: A multikey index is an index on an array field. Each element in the array gets an index key, which supports efficient querying against array fields. Both single field and compound indexes can have an array field, so there are both multikey single field indexes and multikey compound indexes.

Indexes improve query performance:

->Speed up queries ->Reduce disk I/O ->Reduce resources required. ->Support equality matches and range-based operations and return sorted results. -> By default there is one default index per collection, which includes only the _id field. ->Every query should use an index. Best Practices: ->If we insert or update documents, we need to update the index data structure. -> Delete unnecessary or redundant indexes

Relevance Based Search

->Surface records based on a search term. -> Atlas search is a relevance based search.

Equality

->Test exact matches on single field. -> Should be placed first in a compound index. ->Reduce query processing time. ->Retrieves fewer documents.

Which of the following statements are true about the countDocuments() collection method?

->The correct syntax for .countDocuments() is db.collection.countDocuments(<query>). ->We use countDocuments() with an empty document in the query parameter to count all documents in a collection.

What are the effects of creating unbounded documents when embedding data? (Select all that apply.)

->Unbounded documents impact write performance. ->Unbounded documents cause storage problems.

Which of the following scenarios require the use of an ACID transaction? (Select all that apply.)

->Updating a bank database to reflect the transfer of money from Customer A's bank account into Customer B's bank account. ->Updating inventory and shopping cart records when a customer adds an item to their online shopping cart in an ecommerce app.

Find the data on sales to customers less than 30 years old in which the customer satisfaction rating was greater than three. Return only the customer's age and satisfaction rating, the sale date and store location. Do not include the _id field.

->Use the db.collection.find() method on the sales collection. In the query parameter, match documents where the customer was less than 30 years old using the $lt operator. Also match documents where the customer satisfaction rating was greater than three (3) using the $gt operator. ->Add the projection parameter to include only specified fields in the returned results. Include a <field>:<value> expression for each field to return, with the value set to 1 or true. Remember to use dot notation (field.nestedField) when accessing embedded fields, enclosing the field and index in quotation marks. ->Exclude the _id field from returned results by including it in the projection document and setting its value to 0. Solved Code db.sales.find({ "customer.age": { $lt: 30 }, "customer.satisfaction": { $gt: 3 }, }, { "customer.satisfaction": 1, "customer.age": 1, "storeLocation": 1, "saleDate": 1, "_id": 0, });

Query for all sales at the Denver store. Return only the sale date, store location, purchase method and _id fields.

->Use the db.collection.find() method on the sales collection. Match documents for sales at the Denver store using a <field>:<value> expression in the query parameter. ->Add the projection parameter to return only specified fields. Include a <field>:<value> expression for each field to return, with the value set to 1 or true. The _id field will be included in the matching documents by default. Solved Code db.sales.find({ storeLocation: "Denver", }, { storeLocation: 1, saleDate: 1, purchaseMethod: 1, })

Which of the following commands will output to the shell if they are successful?

.commitTransaction()

Multi-Document Transactions

ACID transactions in MongoDB are typically used only by applications where values are exchanged between different parties, such as banking or business applications. If you find yourself in a scenario where a multi-document transaction is required, it's very likely that you will complete a transaction with one of MongoDB's drivers. For now, let's focus on completing and canceling multi-document transactions in the shell to become familiar with the steps.

Returning Specific Data from a Query in MongoDB

Add a Projection Document Projection- Selecting fields to return in our result. To specify fields to include or exclude in the result set, add a projection document as the second parameter in the call to db.collection.find(). Syntax: db.collection.find( <query>, <projection> ) Note: -> Inclusion & exclusion statements can't be combined in projections. -> _id field is an exception Include a Field To include a field, set its value to 1 in the projection document. Syntax: db.collection.find( <query>, { <field> : 1 }) Example: // Return all restaurant inspections - business name, result, and _id fields only db.inspections.find( { sector: "Restaurant - 818" }, { business_name: 1, result: 1 } ) Exclude a Field To exclude a field, set its value to 0 in the projection document. Syntax: db.collection.find(query, { <field> : 0, <field>: 0 }) Example: // Return all inspections with result of "Pass" or "Warning" - exclude date and zip code db.inspections.find( { result: { $in: ["Pass", "Warning"] } }, { date: 0, "address.zip": 0 } ) While the _id field is included by default, it can be suppressed by setting its value to 0 in any projection. // Return all restaurant inspections - business name and result fields only db.inspections.find( { sector: "Restaurant - 818" }, { business_name: 1, result: 1, _id: 0 } ) Note: Inclusion & exclusion statements can't be combined in projections with the exception of the _id field.

Create a Unique Single Field Index

Add {unique:true} as a second, optional, parameter in createIndex() to force uniqueness in the index field values. Once the unique index is created, any inserts or updates including duplicated values in the collection for the index field/s will fail. db.customers.createIndex({ email: 1 }, { unique:true }) MongoDB only creates the unique index if there is no duplication in the field values for the index field/s.

Introduction to MongoDB Aggregation

Aggregation An analysis and summary of data. Stage An aggregation operation is performed on the data. Aggregation Pipeline A series of stages completed one at a time, in order. Aggregation Syntax: db.collection.aggregation([ {$stage_name: {<expression>}}, {$satge_name: {<expression>}}, ])

Search Index with Dynamic Mapping

All fields indexed (except booleans, ObjectIds and timestamps)

$searchMeta

Allows us to see the facets and how many results are in each bucket.

ACID Transactions

An ACID transaction is a group of database operations that must happen together or not at all, ensuring database safety and consistency. ->ACID Transaction should be used in scenario that involve the transfer of value from on record to another. -> ACID Atomicity Consistency Isolation Durability -> A stands for Atomicity: All operations will either succeed or fail together. ->Atomicity: Guarantees that every transaction is "all or nothing" when committing data to a database. For example, we don't want money to be taken from an account but not successfully added to another. ->C stands for Consistency: All changes made by operations are consistent with database constraints. ->Consistency: Guarantees that the data written to the database is consistent with database constraints. For example, if an account balance cannot be less than 0, a transaction would fail before violating this constraint. ->I stands for Isolation: Multiple transactions can happen at the same time without affecting the outcome of the other transaction. ->Isolation: Guarantees that each transaction that is run concurrently leaves the database in the same state as if the transactions were run sequentially. In other words, multiple transactions can happen at the same time without affecting the outcome of the other transactions. ->D stands for Durability: All of the changes that are made by operations in a transaction will persist, no matter what. ->Durability: Guarantees that data is never lost. Data is saved to non-volatile memory, so any modifications made to data by a successful transaction will persist, even in the event of a power or hardware failure.

Cover a query by the Index

An Index covers a query when MongoDB does not need to fetch the data from memory since all the required data is already returned by the index. In most cases, we can use projections to return only the required fields and cover the query. Make sure those fields in the projection are in the index. By adding the projection {name:1,birthdate:1,_id:0} in the previous query, we can limit the returned fields to only name and birthdate. These fields are part of the index and when we run the explain() command, the execution plan shows only two stages: ->IXSCAN - Index scan using the compound index. ->PROJECTION_COVERED - All the information needed is returned by the index, no need to fetch from memory. db.customers.explain().find({ birthdate: { $gte:ISODate("1977-01-01") }, active:true }, {name:1, birthdate:1, _id:0 }).sort({ birthdate:-1, name:1 })

What is the recommended way to avoid the unbounded document sizes that may result from embedding?

Break data into multiple collections and use references.

Facets

Buckets that we group our search results into.

Counting Documents in a MongoDB Collection

Count Documents Use db.collection.countDocuments() to count the number of documents that match a query. countDocuments() takes two parameters: a query document and an options document. Syntax: db.collection.countDocuments( <query>, <options> ) The query selects the documents to be counted. Examples: // Count number of docs in trip collection db.trips.countDocuments({}) // Count number of trips over 120 minutes by subscribers db.trips.countDocuments({ tripduration: { $gt: 120 }, usertype: "Subscriber" })

Sorting and Limiting Query Results in MongoDB

Cursor Pointer to the result set of a query. Cursor Methods -> Chained to queries ->Perform actions on the result set Sorting Results .sort() takes a document that contains one or more field-value pairs. These specify the fields to sort by and the direction of the sort: 1 for ascending or -1 for descending. Use cursor.sort() to return query results in a specified order. Within the parentheses of sort(), include an object that specifies the field(s) to sort by and the order of the sort. Use 1 for ascending order, and -1 for descending order. Syntax: db.collection.find(<query>).sort(<sort>) Example: // Return data on all music companies, sorted alphabetically from A to Z. db.companies.find({ category_code: "music" }).sort({ name: 1 }); To ensure documents are returned in a consistent order, include a field that contains unique values in the sort. An easy way to do this is to include the _id field in the sort. Here's an example: // Return data on all music companies, sorted alphabetically from A to Z. Ensure consistent sort order db.companies.find({ category_code: "music" }).sort({ name: 1, _id: 1 }); Limiting Results Limiting the number of results can enhance performance. Use cursor.limit() to return query results in a specified order. Within the parentheses of limit(), specify the maximum number of documents to return. Syntax: db.companies.find(<query>).limit(<number>) Example: // Return the three music companies with the highest number of employees. Ensure consistent sort order. db.companies .find({ category_code: "music" }) .sort({ number_of_employees: -1, _id: 1 }) .limit(3); For descending order use -1 For ascending order use 1

What is MongoDB's principle for how you should design your data model?

Data that is accessed together should be stored together.

Stages of Aggregation

Each stage is a single operation on the date. Some of the commonly used stages are: $match - Filters for data that matches criteria. $group- Groups documents based on criteria. $sort- Puts the documents in a specified order.

Embedding Vs Referencing

Embedding: When we take related data and insert it into our document. -> Embedding: Used when you have one-to-many or many-to many relationships in the data that's being stored. -> Embedding: Avoids application joins. -> Embedding: Provides better performance for read operations. -> Embedded data models allows developers to update related data in a single write operation. -> Simplify queries and improves overall query performance. ->Has pitfalls like large documents and unbounded documents. Note: ->Embedding data into a single document can create large documents. -> Large documents have to be read into memory in full, which can result in a slow application performance for your end user. ->When embedding continuously adding data without limit creates unbounded documents.the BSON document threshold of 16 MB. ->Unbounded documents may exceed Referencing: we refer to documents in another collection in our document. -> References: Save the _id field of one document in another document as a link between the two. -> Simple and sufficient for most use cases. ->Using references is called linking or data normalization. ->Referencing allows no duplication of data and results in smaller documents. ->With referenced data you have to querying from multiple documents costs extra resources and impacts read performance. ->Referencing data in documents links documents by using the same field.

Finding Documents by Using Logical Operators

Find a Document by Using Implicit $and $and Use implicit $and to select documents that match multiple expressions. For example: db.routes.find({ "airline.name": "Southwest Airlines", stops: { $gte: 1 } }) Find a Document by Using the $or Operator Use the $or operator to select documents that match at least one of the included expressions. For example: db.routes.find({ $or: [{ dst_airport: "SEA" }, { src_airport: "SEA" }], }) Find a Document by Using the $and Operator Use the $and operator to use multiple $or expressions in your query. For example: db.routes.find({ $and: [ { $or: [{ dst_airport: "SEA" }, { src_airport: "SEA" }] }, { $or: [{ "airline.name": "American Airlines" }, { airplane: 320 }] }, ] })

Aborting a Transaction

Here is a recap of the code that's used to cancel a transaction before it completes: const session = db.getMongo().startSession() session.startTransaction() const account = session.getDatabase('< add database name here>').getCollection('<add collection name here>') //Add database operations like .updateOne() here session.abortTransaction()

Using a Transaction

Here is a recap of the code that's used to complete a multi-document transaction: const session = db.getMongo().startSession() session.startTransaction() const account = session.getDatabase('< add database name here>').getCollection('<add collection name here>') //Add database operations like .updateOne() here session.commitTransaction()

Aborting a Transaction

If you find yourself in a scenario that requires you to roll back database operations before a transaction is completed, you can abort the transaction. Doing so will roll back the database to its original state, before the transaction was initiated.

Open a new session by creating a session variable that will store the session object with the following command: const session = db.getMongo().startSession() Start a transaction on the newly created session variable with the following command: session.startTransaction() Create an account variable to reference the accounts collection with the following command: const account = session.getDatabase('bank').getCollection('accounts') Insert a new account for account_holder "Florence Taylor" with an account_id of "MDB454252264", an account_type of "savings", a balance of 100.00, and an empty transfers_complete array. You can do this with the following command: account.insertOne({ account_id: "MDB454252264", account_holder: "Florence Taylor", account_type: "savings", balance: 100.0, transfers_complete: [], last_updated: new Date() }) Fund the account with 100.00 from a checking account with an account_id of "MDB963134500" that belongs to the same account holder. You can do this with the following command: account.updateOne( { account_id: "MDB963134500" }, {$inc: { balance: -100.00 }}) Complete the transaction on the session using the following command: session.commitTransaction()

In this activity, we need to create a new savings account and fund it from an existing checking account in the accounts collection. Since the operations involved affect multiple documents and we need these operations to happen together as a group, we want to use a multi-document transaction. These operations must succeed all together or not at all in order to ensure database consistency. First we create a new variable that will store the session object: const session = db.getMongo().startSession() Next, we start the transaction by using the .startTransaction() method on the session: session.startTransaction() This command gives no output if it succeeds. We create a new variable to store the account collection so that we can reference it while completing the database operations for this transaction. const account = session.getDatabase('bank').getCollection('accounts') Notice that we are using the variable that stores the session object to ensure that the account variable stores the accounts collection in the session instead of the db object. Now we can begin the process of creating and funding a new account. First, we create a new account with the following fields and values: { "account_id": "MDB454252264", "account_holder": "Florence Taylor", "account_type": "savings", "balance": 100.00, "transfers_complete": [], "last_updated": new Date() } We use the .insertOne() operation on the account variable to insert the new document into the accounts collection: account.insertOne({ "account_id": "MDB454252264", "account_holder": "Florence Taylor", "account_type": "savings", "balance": 100.00, "transfers_complete": [] "last_updated": new Date() }) If the account was successfully created, you should see a message in the terminal that resembles the following: { acknowledged: true, insertedId: ObjectId("627a6dc53b7d03489d616c2b") } Next, we need to decrease the account balance of the checking account in order to fund the account that we just created. We use the .updateOne() operation on the account variable to find the account with a account_id of "MDB963134500". Then, we use the $inc operator to decrease the account balance by setting the amount to -100.00. account.updateOne( { account_id: "MDB963134500" }, {$inc: { balance: -100.00 }}) If the second account was successfully updated, the following will appear in the shell: { acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 } Finally, we commit our transaction with the following command: session.commitTransaction() If the transaction was successfully committed, a message resembling the following will appear in the shell: { ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1647437775, i: 5 }), signature: { hash: Binary(Buffer.from("b0d88d5a96372efb9af22021cdd59021741ddb5c", "hex"), 0), keyId: Long("7019511514256113665") } }, operationTime: Timestamp({ t: 1647437775, i: 5 }) } Solved Code const session = db.getMongo().startSession() session.startTransaction() const account = session.getDatabase('bank').getCollection('accounts') account.insertOne({ account_id: "MDB454252264", account_holder: "Florence Taylor", account_type: "savings", balance: 100.0, transfers_complete: [], last_updated: new Date() }) account.updateOne( { account_id: "MDB963134500" }, {$inc: { balance: -100.00 }}) session.commitTransaction()

Open a new session by creating a session variable that will store the session object with the following command: session = db.getMongo().startSession(); Start a transaction on the newly created session variable with the following command: session.startTransaction(); Create an account variable to reference the accounts collection with the following command: const account = session.getDatabase('bank').getCollection('accounts') Add 100 to the balance field of an account with a account_id of "MDB740836066". You can do this with the following command: account.updateOne( { account_id: "MDB740836066" }, {$inc: { balance: 100 }}) Decrease the account balance field of an account with a account_id of "MDB963134500" by 5. You can do this with the following command: account.updateOne( { account_id: "MDB963134500" }, {$inc: { balance: -5 }}) Abort the transaction with the following command: session.abortTransaction()

In this activity, we practiced aborting a multi-document transaction in order to roll back the database to the state it was in before the transaction was initiated. First we create a new variable that will store the session object: const session = db.getMongo().startSession() Next, we start the transaction by using the .startTransaction() method on the session: session.startTransaction() This command gives no output if it succeeds. We create a new variable to store the accounts collection so that we can reference it while completing the database operations for this transaction. const account = session.getDatabase('bank').getCollection('accounts') Notice that we are using the variable that stores the session object to ensure that the account variable stores the account collection in the session instead of the db object. Next we add 100 to the balance of the account with an account_id of "MDB740836066". We use the .updateOne() operation on the account variable to find the account with a account_id of "MDB740836066". Then we increment the balance by 100 using the $inc operator: account.updateOne( { account_id: "MDB740836066" }, {$inc: { balance: 100 }}) If the account was successfully updated, the following will appear in the shell: { acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 } Next, we need to decrease the balance of the account with an account_id of "MDB963134500". We can accomplish this by following the same steps that we used to increase the first account's balance, but, this time, we update the second account's balance by -5: account.updateOne( { account_id: "MDB963134500" }, {$inc: { balance: -5 }}) If the account was successfully updated, the following will appear in the shell: { acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 } In order to abort this multi-document transaction and make sure that the account balances return to their original state, we can run the following command: session.abortTransaction() This command gives no output if it succeeds. Solved Code var session = db.getMongo().startSession() session.startTransaction() var account = session.getDatabase('bank').getCollection('accounts') account.updateOne( { account_id: "MDB740836066" }, {$inc: { balance: 100 }}) account.updateOne( { account_id: "MDB963134500" }, {$inc: { balance: -5 }}) session.abortTransaction()

Querying an Array Elements in MongoDB

Query arrays in documents Example: db.accounts.find({ products: "InvestmentFund"})

Write a query to update a document in the birds collection.In the filter document, use the common_name field with a value of Robin Redbreast to search for the document.In the update document, use the $inc operator to increment the sightings field by 1. Additionally, your query should set a new field called last_updated to the current date and time, using new Date().Add an option to the updateOne() method to create a new document if no documents match your query.

Run the updateOne method on the birds collection to attempt to return and modify a document. In the query, provide a filter document as the first argument with a common_name of Robin Redbreast. In the update document, use the $set operator to set the last_updated field to the current date and time, and the $inc operator to increment the sightings field by 1. In the update document, set the last_updated field to the current date and time using the new Date() method. Provide the upsert option to create a new document if no documents are found matching the query. db.birds.updateOne( { common_name: "Robin Redbreast", }, { $inc: { "sightings": 1, }, $set: { last_updated: new Date(), }, }, { upsert: true, } )

Schema anti-patterns

Schema design patterns are guidelines that help developers plan, organize, and model data. If application is developed with Schema anti-pattern results: ->Sub-optimal performance ->Non-scalable solutions. Most common schema anti-patterns include: ->Massive arrays ->Massive number of collections. ->Bloated documents. ->Unnecessary indexes. ->Queries without indexes. ->Data thats accessed together, but stored in different collections.

Using Transactions in MongoDB

Session: Used to group database operations that are related to each other and should be run together. ->A transaction has a maximum runtime of less than one minute after the first write. ->When using multi-document transactions: -->We must first start a session using a .startSession() method. -->The .startTransaction() and .commitTransaction() methods start and complete a transaction in a session. --> If you want to stop a transaction and roll the database back to its original state you can use the abortTransaction() method.

ACID Transaction in MongoDB

Single-document operations are already atomic in MongoDB. ->No extra steps are needed to provide ACID properties to single-document operations. ->If we need multi-document operations to have ACID properties, we have to wrap them inside a multi-document transaction. Multi-Document Operations: ->Are not inherently atomic. ->Require extra steps to have ACID properties. Multi-Document ACID Transaction: ->MongoDB "locks" resources involved in a transaction. ->Incurs performance cost and affects latency. ->Use multi-document transactions as a precise tool only when ACID properties is absolutely necessary.

Search Indexes

Specify how records are referenced for relevance based search.

$elemMatch

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria. The $elemMatch operator is a valid operator that's included in the MongoDB Shell to find a subdocument that matches specific criteria in an array. Syntax: db.<colllection>.find({<field>:{$elemMatch:{<query1>,<query2>,...}}}) Example: db.account.find({products:{$elemMatch:{$eq:"InvestmentStock"}}})

$push

The $push operator: ->Appends a value to an array. ->If absent, $push adds the array field with the value with the value as its element. ->adds a new value to the hosts array field. Here's an example: db.podcasts.updateOne( { _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8") }, { $push: { hosts: "Nic Raboy" } } )

$set

The $set operator: ->Adds new fields and values to a document. ->Replaces the value of a field with the specified value, as shown in the following code: db.podcasts.updateOne( { _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8"), }, { $set: { subscribers: 98562 } })

Using $search and Compound Operators

The compound operator within the $search aggregation stage allows us to give weight to different field and also filter our results without having to create additional aggregation stages. The four options for the compound operator are "must", "mustNot, "should", and "filter". "must" will exclude records that do not meet the criteria. "mustNot" will exclude results that do meet the criteria. "should" will allow you to give weight to results that do meet the criteria so that they appear first. "filter" will remove results that do not meet the criteria. $search { "compound": { "must": [{ "text": { "query": "field", "path": "habitat" } }], "should": [{ "range": { "gte": 45, "path": "wingspan_cm", "score": {"constant": {"value": 5}} } }] } }

Delete all documents in the birds collection that have a sightings_count of less than or equal to 10.

The deleteMany() method deletes a multiple document in a collection. Append the deleteMany() method to db.birds. Next, pass in the filter to match the documents you want to delete. In this case, use the sighting_count field with the $lte query operator to delete all documents with 10 or fewer sightings. Solved code db.birds.deleteMany({ sightings_count: { $lte: 10 } })

Which of the following is a benefit of the document model?

The document model does not enforce any document structure by default. This means that documents even in the same collection can have different structures.

Updating MongoDB Documents By Using FindAndModify()

The findAndModify() method is used to find and replace a single document in MongoDB. It accepts a filter document, a replacement document, and an optional options object. Note: -> Returns the document that has just been updated ->By default, the `findAndModify()` method returns the unmodified document before it's updated. ->This method finds a document and modifies it. ->This method can insert a document if there are no documents that match the query when the `upsert` option is set to `true` in the options document. ->When the `new` option is set to `true`, `findAndModify()` returns the updated document. Syntax: db.collection.findAndModifty({ query:{}, update:{}, new: true }) example: db.podcasts.findAndModify({ query: { _id: ObjectId("6261a92dfee1ff300dc80bf1") }, update: { $inc: { subscribers: 1 } }, new: true, })

$match and $group in an Aggregation Pipeline

The following aggregation pipeline finds the documents with a field named "state" that matches a value "CA" and then groups those documents by the group key "$city" and shows the total number of zip codes in the state of California. Syntax: db.zips.aggregate([ { $match: { "state": "CA" }, $group: { _id: "$city", totalZips: { $count : { } } } } ])

$sort and $limit in an Aggregation Pipeline

The following aggregation pipeline sorts the documents in descending order, so the documents with the greatest pop value appear first, and limits the output to only the first five documents after sorting. Syntax: db.zips.aggregate([ { $sort: { pop: -1 }, $limit: { 5 } }

Order of Fields in a Compound Index

The order of the fields matters when creating the index and the sort order. It is recommended to list the fields in the following order: Equality, Sort, and Range. ->Equality: field/s that matches on a single field value in a query ->Sort: field/s that orders the results by in a query ->Range: field/s that the query filter in a range of valid values The following query includes an equality match on the active field, a sort on birthday (descending) and name (ascending), and a range query on birthday too. db.customers.find({ birthdate: { $gte:ISODate("1977-01-01") }, active:true }).sort({ birthdate:-1, name:1 }) Here's an example of an efficient index for this query: db.customers.createIndex({ active:1, birthdate:-1, name:1 })

Updating MongoDB Documents by Using UpdateOne()

The updateOne() method accepts a filter document, an update document, and an optional options object. MongoDB provides update operators and options to help you update documents. updateOne() Syntax: db.collection.updateOne(<filter>,<update>,{options})

upsert

The upsert option: -> Insert a document with provided information if matching documents don't exist. ->Creates a new document if no documents match the filtered criteria. Here's an example: db.podcasts.updateOne( { title: "The Developer Hub" }, { $set: { topics: ["databases", "MongoDB"] } }, { upsert: true } )

In the accounts collection, create a compound index using the account_holder, balance and account_type fields. The account_holder field is the first field in the index and should be sorted in ascending order. The balance field is the second field in the index and should also be sorted in ascending order. Finally, the third field should be account_type, also sorted in ascending order. Forgot the command? Check the hints below! Use the explain method to confirm that the index is being used. Be sure to look at the winningPlan field in the output as this contains information about the index that is being used.

To create a compound index, we start by specifying the collection: db.accounts Next, we include the createIndex command to create the index by chaining the command onto the end of the collection: db.accounts.createIndex The createIndex method is used to create a compound index. This method accepts field names and a sort order. To sort items in ascending order, use the 1 sort order, as shown with the account_holder field. To sort items in descending order, use the -1 sort order, as shown with the balance field: // create index db.accounts.createIndex({ account_holder: 1, balance: 1, account_type: 1 }) To confirm the compound index we created is present and being used, we need to run a query that will use the index and view the winningPlan of that query by using the explain() method. First we append the explain() method to the collection and then write our find method for the document like we normally would. In this stage we project only the account_holder, balance, and account_type fields. Finally, run a sort method to sort the documents by balance fields: db.accounts.explain().find( { account_holder:"Andrea", balance:{ $gt:5 }}, { account_holder: 1, balance: 1, account_type:1, _id: 0}).sort({ balance: 1 }) After running the method, you will get a large output in return. The part we are concerned with is the winningPlan object. The winningPlan indicates what was used to find the document, if it was using an index, and what kind of index was used. { winningPlan: { stage: 'PROJECTION_COVERED', transformBy: { account_holder: 1, balance: 1, account_type: 1, _id: 0 }, inputStage: { stage: 'IXSCAN', keyPattern: { account_holder: 1, balance: 1, account_type: 1 }, indexName: 'account_holder_1_balance_1_account_type_1', isMultiKey: false, multiKeyPaths: { account_holder: [], balance: [], account_type: [] }, isUnique: false, isSparse: false, isPartial: false, indexVersion: 2, direction: 'forward', indexBounds: { account_holder: [ '["Andrea", "Andrea"]' ], balance: [ '(5, inf.0]' ], account_type: [ '[MinKey, MaxKey]' ] } } }, rejectedPlans: [] } We can see that the query was using a compound index. We can see that the compound index is being used by the presence of the indexBounds property. Additionally, you can see that the multikey property is set to false. This means that the compound index that we created is present and being used. You may also notice that the FETCH stage is not present in the winningPlan. This is because we are only projecting fields that are in the index, so the FETCH stage can be avoided. Solved Code // create a compound index using the `account_holder`, `balance` and `account_type` fields: db.accounts.createIndex({ account_holder: 1, balance: 1, account_type: 1 }) // Use the explain method to view the winning plan for a query db.accounts.explain().find({ account_holder: "Andrea", balance:{ $gt :5 }}, { account_holder: 1, balance: 1, account_type:1, _id: 0}).sort({ balance: 1 })

Create a multikey single field index on the transfers_complete field. After creating the index, you should see the following output in the terminal (Forgot the command? Check the hints below!): transfers_complete_1 Use the explain() method to view the winningPlan for a query that finds a specific completed_transfers array element and ensure that the multikey single field index you created is being used. The element we want to find is the transfers_complete field set to TR617907396.

To create a multikey index, we start by specifying the collection: db.accounts Next, we include the createIndex command to create the index by chaining the command onto the end of the collection: db.accounts.createIndex Finally, we add the index on the transfers_complete field: db.accounts.createIndex({ transfers_complete: 1 }) To view the explain plans for a query using this index, you can use the explain() method. In our case, we wanted to find a document with the account_id field set to MDB829000996. First we append the explain() method to the accounts collection, followed by the find method: db.accounts.explain().find({ transfers_complete: { $in: ["TR617907396"] } }) After running the method, the winningPlan will show what was used to find the document, if it was using an index, and what kind of index was used. winningPlan: { stage: 'FETCH', inputStage: { stage: 'IXSCAN', keyPattern: { transfers_complete: 1 }, indexName: 'transfers_complete_1', isMultiKey: true, multiKeyPaths: { transfers_complete: [ 'transfers_complete' ] }, isUnique: false, isSparse: false, isPartial: false, indexVersion: 2, direction: 'forward', indexBounds: { transfers_complete: [ '["TR617907396", "TR617907396"]' ] } } }, We can see that the query is using a multikey single field index. The multiKeyPaths object is a map of array field names to array field paths. We can also see that the isMultiKey property is set to true. Solved Code // create a multikey index on the `transfers_complete` field: db.accounts.createIndex({ transfers_complete: 1 }) // use the explain followed by the find method to view the winningPlan for a query that finds a specific `completed_transfers` array element db.accounts.explain().find({ transfers_complete: { $in: ["TR617907396"] } })

In this lab, you will be working with the accounts collection. Once you are using the accounts collection, run db.accounts.findOne() to view the first document in the collection to understand the structure of the document. You should see a document similar to the following: { _id: ObjectId("62d6e04ecab6d8e130497487"), account_id: 'MDB829000996', account_holder: 'Kasper Sørensen', account_type: 'checking', balance: Decimal128("3373.98000000000"), transfers_complete: [ 'TR266268604', 'TR399880553', 'TR277358549', 'TR695865388', 'TR573014677' ] } Create a single field index with a unique constraint on the account_id field to ensure that only one document has a given value for the indexed field.

To create an index with a unique constraint, we start by specifying the collection: db.accounts Next, we include the createIndex command to create the index by chaining the command onto the end of the collection: db.accounts.createIndex() Finally, we add the unique option set to true to ensure that only one document can have a given value for the indexed field. db.accounts.createIndex({ account_id: 1 }, { unique: true }) Solved Code db.accounts.createIndex({ account_id: 1 }, { unique: true })

Run the following explain() command to verify that the account_holder field is using an index while being sure to take a note of the indexName: db.accounts.explain().find({ account_holder: "Puja Barbier" }) Delete the index on the account_holder field. (Forgot the command? Check the hints below!) Run the following explain() method again to verify that the account_holder field is no longer using an index: db.accounts.explain().find({ account_holder: "Puja Barbier" }).

To delete an index, you can run the the command db.accounts.dropIndex("account_holder_1") or db.accounts.dropIndex({ account_holder: 1 }). After running the command you will get an output message that indicates the number of remaining indexes and the result of the command, as shown below: { nIndexesWas: 2, ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1662715201, i: 1 }), signature: { hash: Binary(Buffer.from("f0bfc72ee61ebcc18159589c507fe6725fe28296", "hex"), 0), keyId: Long("7119042987589369858") } }, operationTime: Timestamp({ t: 1662715201, i: 1 }) } Note the nIndexesWas field may differ depending on the number of indexes in the collection at the time of the command. Upon running the explain() method after the index has been deleted, you will notice that the winningPlan.inputStage.stage field no longer indicates the use of an IXSCAN, or index scan, stage. Instead the winningPlan.stage field will indicate the COLLSCAN stage which means the query scanned the entire collection, known as a collection scan, instead. Solved Code db.accounts.dropIndex("account_holder_1")

Deleting Documents in MongoDB

To delete documents, use the deleteOne() or deleteMany() methods. Both methods accept a filter document and an options object. Delete One Document The following code shows an example of the deleteOne() method: db.podcasts.deleteOne({ _id: Objectid("6282c9862acb966e76bbf20a") }) Delete Many Documents ->This method can be used to delete all documents in a collection if you pass an empty filter document to the method (i.e. `db.collection.deleteMany({})`) ->The `deleteMany()` method accepts a filter document and an optional options document as arguments and is used to delete multiple documents in a collection. The following code shows an example of the deleteMany() method: db.podcasts.deleteMany({category: "crime"})

Inserting Documents in a MongoDB Collection

To insert one document. insertOne() Syntax: db.<collection>.insertOne() Example: db.grades.insertOne() To insert more than document. insertMany() Syntax: db.<collection>.insertMany([ <document 1>, <document 2>, <document 3> ]) Note- If the collection doesn't exist then it will be created by default. _id field is not provided by user then it will be generated randomly by mongoDB.

Replacing a Document in MongoDB

To replace a single document replaceOne() To replace documents in MongoDB, we use the replaceOne() method. The replaceOne() method takes the following parameters: filter: A query that matches the document to replace. replacement: The new document to replace the old one with. options: An object that specifies options for the update. Syntax: db.collection.replaceOne(filter,replacement,options) options- options object is not required and is optional

Updating MongoDB Documents by Using updateMany()

To update multiple documents, use the updateMany() method. This method accepts a filter document, an update document, and an optional options object. ->It returns an output message showing the number of matched and modified documents. Note: -> Not an all or nothing operation. ->Will not roll back updates. ->Updates will be visible as soon as they're performed. ->Not appropriate for some use cases. Syntax: The updateMany() method has the following form: db.collection.updateMany( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], hint: <document|string> // Available starting in MongoDB 4.2.1 }) Example db.books.updateMany( { publishedDate: { $lt: new Date("2019-01-01") } }, { $set: { status: "LEGACY" } } )

In this lab, you will use the accounts collection. First, create a query that finds a document with the account_id field equal to MDB829000996. Add the explain() method to your query to view the winningPlan (Forgot the command? Check the hints below!): db.accounts.explain().find(/* your query here */)

To verify that the query is using the correct index, start by writing the find command passing in the account_id field and the value MDB829000996. db.accounts.find({ account_id: "MDB829000996" }) Next, chain the .explain() method to the collection before the find() method. This will return a document that contains the winningPlan for the query which we can use to verify that index is being used. db.accounts.explain().find({ account_id: "MDB829000996" }) Use the output from the command to locate the winningPlan object, which indicates that IXSCAN, or index scan, was chosen for this query. The presence of IXSCAN,in addition to the index name of account_id_1, indicate that the query was using an index to find the document, thus verifying that the query is using the correct index. { winningPlan: { stage: 'FETCH', inputStage: { stage: 'IXSCAN', keyPattern: { account_id: 1 }, indexName: 'account_id_1', isMultiKey: false, multiKeyPaths: { account_id: [] }, isUnique: false, isSparse: false, isPartial: false, indexVersion: 2, direction: 'forward', indexBounds: { account_id: [ '["MDB829000996", "MDB829000996"]' ] } } }, rejectedPlans: [] } Solved Code db.accounts.explain().find({ account_id: "MDB829000996" })

Create a Single Field Indexes

Use createIndex() to create a new index in a collection. Support queries and sort on a single field. Within the parentheses of createIndex(), include an object that contains the field and sort order. Identify indexes by using getIndexes(). Determine the indexes being used in a query by using explain(). db.customers.createIndex({ birthdate: 1 })

Create a Single field Multikey Index

Use createIndex() to create a new index in a collection. Include an object as parameter that contains the array field and sort order. In this example accounts is an array field. db.customers.createIndex({ accounts: 1 })

Create a Compound Index

Use createIndex() to create a new index in a collection. Within the parentheses of createIndex(), include an object that contains two or more fields and their sort order. db.customers.createIndex({ active:1, birthdate:-1, name:1 })

Delete an Index

Use dropIndex() to delete an existing index from a collection. Within the parentheses of dropIndex(), include an object representing the index key or provide the index name as a string. Delete index by name: db.customers.dropIndex( 'active_1_birthdate_-1_name_1' ) Delete index by key: db.customers.dropIndex({ active:1, birthdate:-1, name:1 })

Delete Indexes

Use dropIndexes() to delete all the indexes from a collection, with the exception of the default index on _id. db.customers.dropIndexes() The dropIndexes() command also can accept an array of index names as a parameter to delete a specific list of indexes. db.collection.dropIndexes([ 'index1name', 'index2name', 'index3name' ])

Check if an index is being used on a query

Use explain() in a collection when running a query to see the Execution plan. This plan provides the details of the execution stages (IXSCAN , COLLSCAN, FETCH, SORT, etc.). The IXSCAN stage indicates the query is using an index and what index is being selected. The COLLSCAN stage indicates a collection scan is perform, not using any indexes. The FETCH stage indicates documents are being read from the collection. The SORT stage indicates documents are being sorted in memory. db.customers.explain().find({ birthdate: { $gt:ISODate("1995-08-01") } }) db.customers.explain().find({ birthdate: { $gt:ISODate("1995-08-01") } }).sort({ email:1 })

Check if an index is being used on a query

Use explain() in a collection when running a query to see the Execution plan. This plan provides the details of the execution stages (IXSCAN , COLLSCAN, FETCH, SORT, etc.). ->The IXSCAN stage indicates the query is using an index and what index is being selected. ->The COLLSCAN stage indicates a collection scan is perform, not using any indexes. ->The FETCH stage indicates documents are being read from the collection. ->The SORT stage indicates documents are being sorted in memory. db.customers.explain().find({ accounts: 627788 })

Check if an index is being used on a query

Use explain() in a collection when running a query to see the Execution plan. This plan provides the details of the execution stages (IXSCAN , COLLSCAN, FETCH, SORT, etc.). Some of these are: ->The IXSCAN stage indicates the query is using an index and what index is being selected. ->The COLLSCAN stage indicates a collection scan is perform, not using any indexes. ->The FETCH stage indicates documents are being read from the collection. ->The SORT stage indicates documents are being sorted in memory. db.customers.explain().find({ birthdate: { $gte:ISODate("1977-01-01") }, active:true }).sort({ birthdate:-1, name:1 })

View the Indexes used in a Collection

Use getIndexes() to see all the indexes created in a collection. db.customers.getIndexes()

View the Indexes used in a Collection

Use getIndexes() to see all the indexes created in a collection. There is always a default index in every collection on _id field. This index is used by MongoDB internally and cannot be deleted. db.customers.getIndexes()

To add multiple elements to the array.

Use the $each modifier to add multiple elements to the array. Example: Write a query that will update a document with an _id of ObjectId("6268471e613e55b82d7065d7") and add the following to the diet array without removing any existing values: db.birds.updateOne( { _id: ObjectId("6268471e613e55b82d7065d7") }, { $push: { diet: { $each: ["newts", "opossum", "skunks", "squirrels"] }, }, } )

Find the number of sales made using a coupon at the Denver location.

Use the db.collection.countDocuments() method to count the documents that match a query. This method takes a query parameter that specifies selection criteria and an optional options parameter that affects count behavior. Use <field>:<value> expressions in the query parameter to specify the two equality constraints. In this case, we included storeLocation: Denver and couponUsed: true. Note that the options parameter is not needed because the task does not require any modifications to the count behavior, like specifying a maximum number of documents to count. Correct answer: 157 Solved Code db.sales.countDocuments({ storeLocation: "Denver", couponUsed: true })

Find the number of sales that included a laptop that cost less that $600.

Use the db.collection.countDocuments() to count the count of documents that match a query. This method takes two parameters: a required query parameter that specifies selection criteria and an optional options parameter that affects the count behavior. Both parameters take the form of a document. Use the $elemMatch operator in the query parameter to specify the two criteria on the elements of the items array such that at least one array element meets both criteria. Use a <field>:<value> expression to match documents in which the items's name is equal to "laptop". Use the $lt operator to match documents in which the item's "price" is less than 600. Note that the options parameter is not needed because the task does not require any modifications to the count behavior, like specifying a maximum number of documents to count. Correct answer: 397 Solved Code db.sales.countDocuments({ items: { $elemMatch: { name: "laptop", price: { $lt: 600 } } } } )

Find the total number of documents in the sales collection.

Use the db.collection.countDocuments() to count the number of documents that match a query. This method takes two parameters: a required query parameter that specifies selection criteria and an optional parameter,options, which affects the count behavior. Both parameters take the form of a document. Specify an empty document in the query parameter to count all documents in a collection. Note that the options parameter is not needed because the task does not require any modifications to the count behavior, like specifying a maximum number of documents to count. Correct answer: 5000 Solved Code db.sales.countDocuments({});

Find data on all sales from the Seattle and New York stores. Return all data except the purchase method, customer information, and whether a coupon was used.

Use the db.collection.find() method on the sales collection. In the query parameter, match documents on all sales from the Seattle and New York stores using the $in query operator. $in matches documents where the field value is equal to any of the values in the specified array or the field does not exist. Add the projection parameter to exclude specified fields in the returned results. Include a <field>:<value> expression for each field to exclude, with the value set to 0 or false. Remember that the _id field is included by default. In this case, we set couponUsed, purchaseMethod, and customer to 0. Solved Code db.sales.find({ storeLocation: { $in: ["Seatt

Return the data on all sales made online using a coupon, ordered by date from the most recent to the oldest. (Forgot the command?

Use the db.collection.find() method on the sales collection. Use <field>:<value> expressions in the query filter document to specify equality conditions. In this case, pass in { purchaseMethod: "Online", couponUsed: true } to find all documents purchased online with a coupon Use cursor.sort() to specify the order in which the query returns matching documents. The sort() method takes an object consisting of one or more key-value pairs, in which the keys are the fields to sort by and the values represent the sort direction (1 or -1 to specify an ascending or descending sort order respectively.) In this case the object consists of one key-value pair, saleDate: -1, to sort by the saleDate field in descending order (as the desired ordering is by date of sale from newest to oldest.) db.sales.find({ purchaseMethod: "Online", couponUsed: true}).sort({ saleDate: -1 })

Return the data on the three most recent sales made from the London store that included one or more of the following items: a laptop, a backpack or printer paper.

Use the db.collection.find() on the sales collection. The $in operator matches documents in which the items.name array contains one or more of the specified items (a laptop, a backpack or printer paper). The <field>:<value> expression matches documents where the value of the storeLocation field is "London". cursor.sort()specifies the order in which the query returns matching documents. The sort() method takes an object consisting of one or more key-value pairs, in which the keys are the fields to sort by and the values represent the sort direction (1 or -1 to specify an ascending or descending sort order respectively.) In this case the object consists of one key-value pair, saleDate: -1, to sort by the saleDate field in descending order. cursor.limit() specifies the maximum number of results to return from the query. The call to the limit() method should come after sort() so that query results are sorted before the limit is applied.In this case, we set limit to 3. db.sales.find({ "items.name": { $in: ["laptop", "backpack", "printer paper"] }, "storeLocation": "London", }).sort({ saleDate: -1, }).limit(3)

Update the last_seen date to 2022-01-01 for Blue Jay and Grackle in the birds collection.

Use the updateMany() method on the birds collection to update multiple documents. The updateMany() method accepts a filter, an update, and an optional options object. db.collection.updateMany(filter, update, [options]) In this example, our filter will look for the common_name values of Blue Jay and Grackle. The $in operator is used to match documents that have a common_name field that is equal to one of the bird names provided in the filter. In the update, we set the last_seen field to ISODate("2022-01-01"). The ISODate() function is used to convert the date string into a Date object that MongoDB can store. db.birds.updateMany( { common_name: { $in: ["Blue Jay", "Grackle"], }, }, { $set: { last_seen: ISODate("2022-01-01"), }, } )

Database Indexes

Used by developers and database administrators to make their frequent database queries easier and more efficient.

Difference between Without indexes and with indexes?

Without indexes ->MongoDB reads all documents (collection scan) ->Sorts results in memory. With Indexes ->MongoDB only fetches the document identified by the index based on the query. ->Return results faster

You have a database called bird_data with a collection of information about bird species. In the future, we'll add new animals to the database and collection. Before we do that, we have to add a class field and set that field to bird in all of the existing documents in the collection

You can access the collection you want to use with dot notation: db.birds Use the aggregate method to set up the aggregation pipeline. We use the $set stage to add a new field to the documents in the collection. We add a field called class and set the value of that field to "bird". db.birds.aggregate([ { $set: { 'class': 'bird' } } ]) Solved Code db.birds.aggregate([ { $set: { 'class': 'bird' } } ])

You have a database called bird_data with a collection of sightings. We want to see the total number of sightings of Eastern Bluebirds in 2022.

You can access the collection you want to use with dot notation: db.sightings Use the aggregate method to set up the aggregation pipeline. The first aggregation stage will be $match which will find documents where the date field contains a value greater than ISODate("2022-01-01T00:00:00.0Z") and less than ISODate("2023-01-01T00:00:00.0Z"). The $match stage will also find documents where the species_common field is "Eastern Bluebird". db.sightings.aggregate([ { $match: { date: { $gt: ISODate('2022-01-01T00:00:00.0Z'), $lt: ISODate('2023-01-01T00:00:00.0Z') }, species_common: 'Eastern Bluebird' } } ]) The last stage that we include is $count. The $count stage creates a field called bluebird_sightings_2022, which includes the value from the count of how many documents are currently in the pipeline. db.sightings.aggregate([ { $match: { date: { $gt: ISODate('2022-01-01T00:00:00.000Z'), $lt: ISODate('2023-01-01T00:00:00.000Z') }, species_common: 'Eastern Bluebird' } }, { $count: 'bluebird_sightings_2022' } ]) Solved Code db.sightings.aggregate([ { $match: { date: { $gt: ISODate('2022-01-01T00:00:00.000Z'), $lt: ISODate('2023-01-01T00:00:00.000Z') }, species_common: 'Eastern Bluebird' } }, { $count: 'bluebird_sightings_2022' } ])

You have a database called bird_data with a collection of sightings. We're starting to put together our end-of-the-year report on how many birds were seen. We want to put the sightings records in their own collection so that we can manipulate the data later. To do that, you'll use the aggregation stage $out to create a new collection.

You can access the collection you want to use with dot notation: db.sightings Use the aggregate method to set up the aggregation pipeline. The first stage that we use is $match, which accepts a simple query to filter for specific documents. In this case, $match will filter for documents where "date" is the year 2022. The dates of the sightings are stored in BSON Date format. This means that using ISODate formatting in our query allows us to use comparison operators. Those comparison operators are $gt (greater than) to find dates after 0:00 on January 1, 2022, and $lt (less than) to find dates before 0:00 on January 1, 2023. db.sightings.aggregate([ { $match: { date: { $gte: ISODate('2022-01-01T00:00:00.0Z'), $lt: ISODate('2023-01-01T00:00:00.0Z') } } } ]) Then we want to add an $out stage to create a new collection with those matched documents, called 'sightings_2022'. db.sightings.aggregate([ { $match: { date: { $gte: ISODate('2022-01-01T00:00:00.000Z'), $lt: ISODate('2023-01-01T00:00:00.000Z') } } }, { $out: 'sightings_2022' } ]) To confirm that we have created the collection and populated it succesfully, we can run a findOne() operation with db.sightings_2022.findOne(). Solved Code db.sightings.aggregate([ { $match: { date: { $gte: ISODate('2022-01-01T00:00:00.0Z'), $lt: ISODate('2023-01-01T00:00:00.0Z') } } }, { $out: 'sightings_2022' } ]) db.sightings_2022.findOne()

You have a database called bird_data with a collection of sightings. We want to use this data to find the birds that are sighted furthest North.

You can access the collection you want to use with dot notation: db.sightings Use the aggregate method to set up the aggregation pipeline. The first stage will be $sort which accepts a field to sort by, and -1 to indicate that the sort should show the greatest value to the lowest value. In this case, location.latitude will be the field that we sort by. Latitudinal values are greater further North, so we sort from highest to lowest. db.sightings.aggregate([ { $sort: { 'location.latitude': -1 } } ]) Next, use $limit to return only the 4 most northerly sightings in the newly sorted order. db.sightings.aggregate([ { $sort: { 'location.latitude': -1 } }, { $limit: 4 } ]) Solved Code db.sightings.aggregate([ { $sort: { 'location.latitude': -1 } }, { $limit: 4 } ])

You have a database called bird_data with a collection of sightings. There is a lot of data in each document, but we want to return only a list of the time of the sighting and the common name of the bird that was sighted.

You can access the collection you want to use with dot notation: db.sightings Use the aggregate method to set up the aggregation pipeline. The aggregation stage will be $project which shows the indicated fields in each record of our collection. In this case, species_common and date. We don't need to see the _id, so we can project that field out by setting it's value to 0 in the $project stage. db.sightings.aggregate([ { $project: { _id: 0, species_common: 1, date: 1 } } ]) Solved Code db.sightings.aggregate([ { $project: { _id: 0, species_common: 1, date: 1 } } ])

Run the command that returns an array of indexes on the transfers collection. Forgot the command? Check the hints below! After running the command, notice that the indexes are returned in an array: [ { v: 2, key: { _id: 1 }, name: '_id_' }, ]

You can access the list of indexes on the collection you want to use with: db.<collection>.getIndexes() getIndexes() returns an array that holds a list of documents that identify and describe the existing indexes on the collection. Solved Code db.transfers.getIndexes()

Structure of an Aggregation Pipeline

db.collection.aggregate([ { $stage1: { { expression1 }, { expression2 }... }, $stage2: { { expression1 }... } } ])

Create a query that matches all documents with a transactions sub document that contains an amount less than or equal to $4500 and a transaction_code of "sell" in the transactions collection.

db.transactions.find({ transactions: { $elemMatch: { amount: { $lte: 4500 }, transaction_code: "sell" }, }, })

Finding Documents in a MongoDB Collection

find() Syntax: db.<collection>.find() To find a specific document db.<collection>.find({field: {$eq:<value>}})


Related study sets

horizontal and vertical lines chapter 4 algebra

View Set

Social Studies Final Exam Chapter 19-24

View Set

Chapter 7 Microbiology - Control of Microbial Growth

View Set