Getting started with MongoDB simple practice

Getting started with MongoDB simple practice

1. Why use MongoDB?

Traditional computer applications mostly use relational databases to store data, such as MySql, Sqlite, etc. that you may be familiar with. Its characteristic is that data is stored in the form of tables. The database is composed of neatly arranged tables, just like an Excel sheet. Each table has several columns, such as a student information table, which may contain student ID, name, gender, year of enrollment, college entrance examination results, hometown, etc. . And each row of the table is the specific information of each student. In enterprise-level applications and the pre-Internet era, relational databases are almost the best choice. A relational database is characterized by a neat and uniform organization, which is very convenient for data description, insertion, and search.

Imagine a traditional online clothing store, its main data may be stored in a form called products, the form may contain these columns: product number (ID), name (Name), business (brand), main Category (cate), sub-category (sub-cat), retail price (price), promotion or not, etc. If a user wants to find the numbers and names of all the shoes being promoted with a price of less than 300 yuan, he can execute a SQL statement similar to the following:

SELECT ID, name FROM products WHERE cate='shoes' AND price<300 and AND promotion=true;

SQL has powerful in-depth query capabilities, which can meet various query requirements. And if you want to add and delete data, the cost is also very low. These are one of the advantages of SQL, but with the rise of the Internet and the diversification of data forms, the stable SQL form has gradually shown its disadvantages in some areas. Let us illustrate with an example. Consider a blog background system. If we use a relational database to build a form for each blog (article), the form will probably include the following columns:

ID Title Description Author Content Likes
A_1 Title1 Political Article Joe Content 1 12
A_2 Title2 Humorous Story Sam Content 2 50

At this time, it is very convenient to use SQL database to store, but if we want to add comment function to each article, we will find that each article may have multiple comments, and this number is dynamically changing, and each comment also includes several Item content: the person who commented, the time of the comment, and the content of the comment. At this time, it is very difficult to stuff all these contents into the above-mentioned table. The usual practice is to create a separate table for comments:

ID Author Time Content Article
C_1 Anna 2014-12-26 08:23 Really good articles! A_1
C_2 David 2014-12-25 09:30 I like it! A_1

Similarly, each article may have several tags. The label itself is another form:

ID Category Tags Content Article
T_1 Anna 2014-12-26 08:23 Really good articles! A_1
T_2 David 2014-12-25 09:30 I like it! A_2

The blog form should be linked to these related forms through the foreign key (may also include other forms such as author, publisher, etc.). In this way, when we make a query, for example, "find out articles with no less than 3 comments that are tagged as "political comment" and the author is Sam", it will involve complex cross-table query, which requires a lot of Use joinstatements. This kind of cross-table query not only reduces the query speed, but also these statements are not easy to write.

So, if you use MongoDB database to implement, how can you design the data model? It's very simple, like the following [1] :

 _id: POST_ID
   title: TITLE_OF_POST, 
   description: POST_DESCRIPTION,
   author: POST_BY,
   tags: [TAG1, TAG2, TAG3],
   likes: TOTAL_LIKES, 
   comments: [	
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
      },
      {
         user:'COMMENT_BY',
         message: TEXT,
         dateCreated: DATE_TIME,
      }
   ]

In MongoDB, each blog post is stored in the form of a document, and the document contains many items, such as title tagsetc., each item is key-valuein the form, that is, there is a name of the item, for example title, and its Value TITLE_OF_POST. The important thing is that keythere can be more than one values, and they should be []enclosed in parentheses.

This "relaxed" data storage form is very flexible, and MongoDB does not limit the number of each keycorresponding values. For example, if some articles have no comments, its value is an empty set, which is no problem at all; some articles have a lot of comments and can be inserted without limitation. More flexible is that MongoDB does not require different documents in the same collection (equivalent to SQL table) to have the same key. For example, in addition to the above-mentioned document organization, the articles represented by some documents may not have the item of likes. For example, some articles may have more items, for example, there may be dislikes and so on. These different documents can be flexibly stored in the same collection, and the query is also very simple, because they are all in one document, and there is no need to perform various cross-document queries. And this kind of MongoDB-style storage also facilitates data maintenance. For a blog post, all relevant data is in this document, and there is no need to consider how many tables are involved in a data operation.

Of course, in addition to the above advantages, MongoDB has many other advantages. For example, MongoDB data is stored in JSON (Javascript Object Notation) (in the form of the above key-value), and almost all web applications have It is based on Javascript. Therefore, the format of the stored data and the application data are highly consistent, and no conversion is required. More advantages can be viewed: [2] .

2. About this article

This minimalist tutorial, or notes, is not a tutorial covering all aspects of MongoDB. The so-called minimalism means that only the most important and commonly used content is selected for example-based introduction, so that readers can quickly get started in the shortest time and can smoothly follow-up in-depth learning.

Specifically, the features of this tutorial are:

  • Not comprehensive, but practical. Cover only the core part;
  • Be guided by a large number of examples;
  • It only takes about 2 hours to read and operate by hand;

You do not need to have a special foundation to read this article, but it is best to know the basic concepts of the database, if you are familiar with SQL, it would be better.

3. Installation and environment

MongoDB can run on mainstream platforms such as Windows, Linux, Mac OS X, and it is very easy to download and install, and very friendly. The examples in this document use MongoDB 2.6 and have been tested on OS X. There are good reasons to believe that it will run smoothly on other platforms.

Linux installation and settings can refer to: http://www.w3cschool.cc/mongodb/mongodb-linux-install.html;

If the above steps are all running smoothly, you can skip to the next section.

4. Create collections and delete collections

After performing step 6 in the previous section, you will see the command line display: `connecting to: test`, where `test` is the default database. Here we can create a new database. Type in the command line:
use tutorial

This creates a new tutorialdatabase called . You can execute

show databases

To display the current database. But at this time, because our new database is empty, it will display something like this:

admin  (empty)
local  0.078GB

We try to add a collection to our database. The collection in MongoDB is similar to the table in SQL:

db.createCollection('author')

If it goes well, it will show:

{ "ok" : 1 }

Indicates that the creation was successful.

You can go back and execute:

show databases

At this time, our tutorial collection is already among them. You can execute again

show collections

You can see that the created collection author is also in it.

We don't need the author collection for the time being, so we can execute:

db.author.drop()

To delete it. At this time, if you execute show collectionsit again, you will no longer see our author.

There is only one main point to remember in this section: collections are similar to SQL tables and Excel tables.

5. Insert

Imagine a condensed version of "Douban Movie". We need to create a database to store the information of each movie, the movie information includes:

  • Movie name
  • director
  • Starring (maybe more than one)
  • Type label (possibly multiple)
  • Release date
  • Likes
  • Dislike number
  • User comments (possibly multiple)

Obviously we need to create a collection called movies first:

db.createCollection('movie')

Then, we can insert data:

db.movie.insert(
 {
   title: 'Forrest Gump', 
   directed_by: 'Robert Zemeckis',
   stars: ['Tom Hanks', 'Robin Wright', 'Gary Sinise'],
   tags: ['drama', 'romance'],
   debut: new Date(1994,7,6,0,0),
   likes: 864367,
   dislikes: 30127,
   comments: [	
      {
         user:'user1',
         message: 'My first comment',
         dateCreated: new Date(2013,11,10,2,35),
         like: 0 
      },
      {
         user:'user2',
         message: 'My first comment too!',
         dateCreated: new Date(2013,11,11,6,20),
         like: 0 
      }
   ]
}
)

Please note that before inserting data here, we do not need to declare what items are in the movie collection. We can insert it directly~ This is different from SQL. SQL must first declare which columns are in a table, but MongoDB does not need it.

Copying the above example into the command line should work smoothly, but I strongly recommend you to type it manually or enter a movie you like. insertThere are several points to note in operation:

  • 1. Different key-values ​​need to be separated by commas, and a colon is used in the middle of key:value;
  • 2. If a key has multiple values, use [] for value. Even if there is only one value, add [] for subsequent additions;
  • 3. The entire "data block" should be enclosed in {};

If you insertsee WriteResult({ "nInserted" : 1 })it later , the writing was successful.

At this time, you can use query to return the data in the database:

db.movie.find().pretty()

Here find()is empty, indicating that we do not limit and filter, similar to SQL without WHEREstatements. The pretty()output is the formatted data, you can try it yourself pretty().

Observing find()the results carefully , you will find that there is one more '_id'thing called , which is an ID number automatically created by the database. In the same database, the ID number of each document is different.

We can also enter multiple data at the same time:

db.movie.insert([
 {
   title: 'Fight Club', 
   directed_by: 'David Fincher',
   stars: ['Brad Pitt', 'Edward Norton', 'Helena Bonham Carter'],
   tags: 'drama',
   debut: new Date(1999,10,15,0,0),
   likes: 224360,
   dislikes: 40127,
   comments: [	
      {
         user:'user3',
         message: 'My first comment',
         dateCreated: new Date(2008,09,13,2,35),
         like: 0 
      },
      {
         user:'user2',
         message: 'My first comment too!',
         dateCreated: new Date(2003,10,11,6,20),
         like: 14 
      },
      {
         user:'user7',
         message: 'Good Movie!',
         dateCreated: new Date(2009,10,11,6,20),
         like: 2
      }
   ]
},
{
   title: 'Seven', 
   directed_by: 'David Fincher',
   stars: ['Morgan Freeman', 'Brad Pitt',  'Kevin Spacey'],
   tags: ['drama','mystery','thiller'],
   debut: new Date(1995,9,22,0,0),
   likes: 134370,
   dislikes: 1037,
   comments: [	
      {
         user:'user3',
         message: 'Love Kevin Spacey',
         dateCreated: new Date(2002,09,13,2,35),
         like: 0 
      },
      {
         user:'user2',
         message: 'Good works!',
         dateCreated: new Date(2013,10,21,6,20),
         like: 14 
      },
      {
         user:'user7',
         message: 'Good Movie!',
         dateCreated: new Date(2009,10,11,6,20),
         like: 2
      }
   ]
}
])

If it goes well, it will show:

BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]

On the surface, we successfully inserted two data. Note that the bulk insert format is as follows: db.movie.insert([{ITEM1},{ITEM2}]). Several movies need to be enclosed in [].

Please note that although collection do not need to insert the statement, but the expression of key same meaning, the name should be the same, for example, if we use a documentation directed_byto represent the director, then in the other documents have to keep the same name (instead directorof Category). Different names are not impossible, technically feasible, but will bring difficulties to query and update.

Well, here, we have a database called tutorial, which has a collection called movie, and there are three records in movie. Next we can query it.

6. Query

We have already touched on the simplest query in the previous section db.movie.find().pretty(). MongoDB supports a variety of in-depth query functions. Let’s start with the simplest example to find all the movies directed by David Fincher:

db.movie.find({'directed_by':'David Fincher'}).pretty()

Will return to the two films "Fight Club" and "The Seven Deadly Sins". This search WHEREis very similar to the SQL statement.

You can also set multiple conditions. For example, find out the movie directed by David Fincher and starring Morgan Freeman:

db.movie.find({'directed_by':'David Fincher', 'stars':'Morgan Freeman'}).pretty()

Here, the relationship between the two conditions is AND, and only movies that meet both conditions at the same time will be output. In the same way, multiple conditions can be set, so I won’t repeat them.

Conditions can also be an OR relationship, such as finding movies starring Robin White or Morgan Freeman:

db.movie.find(
{
  $or: 
     [  {'stars':'Robin Wright'}, 
        {'stars':'Morgan Freeman'}
     ]
}).pretty()

Pay attention to the slightly more complicated parentheses.

You can also set a range of searches, such as finding movies that are liked by more than 500,000 people:

db.movie.find({'likes':{$gt:500000}}).pretty()

Also pay attention to the slightly more complicated parentheses. Note that in these queries, the single quotes for the key are optional, that is to say, the above statement can also be written as:

db.movie.find({likes:{$gt:500000}}).pretty()

Similarly, movies with fewer than 200,000 likes:

db.movie.find({likes:{$lt:200000}}).pretty()

Similar operators include:: $lteless than or equal to;: $gtegreater than or equal to;: $nenot equal to.

Note that for keys containing multiple values, you can also use find to query. such as:

db.movie.find({'tags':'romance'})

Will return to "Forrest Gump", although its label has both romance and drama, it only needs to match one.

If you know exactly that there is only one result returned, you can also use findOne:

db.movie.findOne({'title':'Forrest Gump'})

If there are multiple results, the first one will be returned in the order of disk storage. Please note that since it findOne()comes with pretty mode, it cannot be added pretty(), and an error will be reported.

If there are many results and you only want to display a part of them, you can use limit()sum skip(), the former indicates the number of outputs, and the latter indicates the number from the second result. such as:

db.movie.find().limit(2).skip(1).pretty()

Then skip the first part and select two movies from the second.

7. Partial query

In the fifth section, we talked about the findusage, but for the items that meet the conditions, we return the entire JSON file. This is similar to SQL SELECT *. Sometimes, what we need is only part of the data. At this time, findthe partial query function comes in handy. Let's look at an example first, returning the name and premiere date of a movie whose tags is drama.

db.movie.find({'tags':'drama'},{'debut':1,'title':1}).pretty()

The database will return:

{
	"_id" : ObjectId("549cfb42f685c085f1dd47d4"),
	"title" : "Forrest Gump",
	"debut" : ISODate("1994-08-05T16:00:00Z")
}
{
	"_id" : ObjectId("549cff96f685c085f1dd47d6"),
	"title" : "Fight Club",
	"debut" : ISODate("1999-11-14T16:00:00Z")
}
{
	"_id" : ObjectId("549cff96f685c085f1dd47d7"),
	"title" : "Seven",
	"debut" : ISODate("1995-10-21T16:00:00Z")
}

The second parameter found here is used to control the output, 1 means to return, and 0 means not to return. The default value is 0, but it _idis the exception, so if you do not want to export _id, you need to explicitly declare:

db.movie.find({'tags':'drama'},{'debut':1,'title':1,'_id':0}).pretty()

8. Update

In many cases, you need to update your database. For example, if someone likes a movie, then you need to update the corresponding database. For example, someone has liked the "Seven Deadly Sins", and its original number of likes is 134370, then you need to update to 134371. You can do it like this:
db.movie.update({title:'Seven'}, {$set:{likes:134371}})

The first brace indicates the object to be selected, and the second indicates the data to be changed. Please note that the above operation is quite unrealistic, because you first need to know what the previous number is, and then add one, but usually if you don't read the database, you won't know this number (134370). MongoDB provides an easy way to perform incremental operations on existing entries. Assuming that someone has clicked two likes on "The Seven Deadly Sins", you can:

db.movie.update({title:'Seven'}, {$inc:{likes:2}})

If you check, you will find that the number of likes has become 134373, which is used here $inc. In addition to incremental updates, MongoDB also provides a lot of flexible update options, see: http://docs.mongodb.org/manual/reference/operator/update-field/ for details.

Note that if there are multiple movies that meet the requirements. By default, only the first one will be updated. If you want to update multiple at the same time, you need to set {multi:true}it as follows:

db.movie.update({}, {$inc:{likes:10}},{multi:true})

The number of likes for all movies has increased by 10.

Note that the above update operation will replace the original value, so if you want to add a value based on the original value, you should use it $push, for example, to add a popular tag to the "Seven Deadly Sins".

db.movie.update({'title':'Seven'}, {$push:{'tags':'popular'}})

You will find that "The Seven Deadly Sins" now has four tabs:

	"tags" : [
		"drama",
		"mystery",
		"thiller",
		"popular"
	],

9. Delete

The deletion syntax is very similar to that of find. For example, to delete a movie labeled romance, then:

db.movie.remove({'tags':'romance'})

Considering that our database entries are unusually scarce, it is not recommended that you execute this command~

Note that the above example will delete all movies whose tags contain romance. If you only want to delete the first one, then

db.movie.remove({'tags':'romance'},1)

Without any restrictions:

db.movie.remove()

All files in the movie collection will be deleted.

10. Indexing and Sorting

Adding an index to some keys in the document can speed up the search. This is not difficult to understand. If there is no index, if we want to find the movie named Seven, we must search all the documents one by one. If you add an index value to the key of the name, a mapping is established between the character string of the movie name and the number, so that the search will be much faster. The same is true when sorting, so I won’t go into details. The way to add an index to a key in MongoDB is very simple. For example, if we want to index the director key, we can:

db.movie.ensureIndex({directed_by:1})

Here 1 is an ascending index, if you want a descending index, use -1.

MongoDB supports sorting the output, such as sorting by name:

db.movie.find().sort({'title':1}).pretty()

Similarly, 1 is in ascending order and -1 is in descending order. The default is 1.

db.movie.getIndexes()

All indexes will be returned, including their names.

and

db.movie.dropIndex('index_name')

The corresponding index will be deleted.

11. Aggregation

MongoDB supports GROUP BYoperations similar to SQL . For example, when there is a list of students' grades, we can find out how many students are in each grade. In order to achieve this operation, we need to slightly modify our database. Execute the following three commands:

db.movie.update({title:'Seven'},{$set:{grade:1}})
db.movie.update({title:'Forrest Gump'},{$set:{grade:1}})
db.movie.update({title:'Fight Club'},{$set:{grade:2}})

These items are to add a virtual rating to each movie, the first two are classified as first-level, and the latter is second-level.

Here you can also see the power of MongoDB: you can dynamically add various new projects subsequently.

We first use aggregation to find out how many levels there are in total.

db.movie.aggregate([{$group:{_id:'$grade'}}])

Output:

{ "_id" : 2 }
{ "_id" : 1 }

Note that 2 and 1 here refer to levels, not the number of movies per level. See this example more clearly:

db.movie.aggregate([{$group:{_id:'$directed_by'}}])

Here is aggregated according to the director's name. Output:

{ "_id" : "David Fincher" }
{ "_id" : "Robert Zemeckis" }

Then we have to find out how many movies each director has:

db.movie.aggregate([{$group:{_id:'$directed_by',num_movie:{$sum:1}}}])

Will output:

{ "_id" : "David Fincher", "num_movie" : 2 }
{ "_id" : "Robert Zemeckis", "num_movie" : 1 }

Note that the 1 behind $sum means just adding up the number of movies, but we can also count other data, such as the two directors who have more likes:

 db.movie.aggregate([{$group:{_id:'$directed_by',num_likes:{$sum:'$likes'}}}])

Output:

{ "_id" : "David Fincher", "num_likes" : 358753 }
{ "_id" : "Robert Zemeckis", "num_likes" : 864377 }

Note that these data are purely fictitious!

Besides $sum, there are some other operations. such as:

db.movie.aggregate([{$group:{_id:'$directed_by',num_movie:{$avg:'$likes'}}}])

The statistics are average.

db.movie.aggregate([{$group:{_id:'$directed_by',num_movie:{$first:'$likes'}}}])

Returns the number of likes for the first movie in each director's movie.

For various other operations, please refer to: http://docs.mongodb.org/manual/reference/operator/aggregation/group/.

12. All or Nothing?

MongoDB supports atomic operations within a single document. This means that multiple instructions on the same document can be put together, and they can either be executed together or not. It will not be executed in half. In some cases, it is necessary to ensure that multiple executions are executed sequentially. For example, a scenario: an e-commerce website, the user queries the remaining quantity of a certain product, and the user purchases the product, these two operations must be performed together. Otherwise, suppose we execute the remaining number of queries first. This is assumed to be 1, and the user will then purchase, but if other operations are added between these two operations, for example, another user preemptively purchased, then the original purchase user’s purchase The behavior will cause database errors, because in fact this product and out of stock. But because querying the remaining quantity and purchasing is not within an "atomic operation", such an error occurs [2] .

MongoDB provides findAndModifymethods to ensure atomic operation. For example:

db.movie.findAndModify(
			{
			query:{'title':'Forrest Gump'},
			update:{$inc:{likes:10}}
			}
		      )

Query is to find matching documents, which is the same as find, while update is to update the item likes. Note that since MongoDB only supports atomic operations for a single document, if more than one document is queried, only the first document will be operated on.

findAndModifyMore operations are also supported, see: http://docs.mongodb.org/manual/reference/command/findAndModify/ for details.

13. Text Search

In addition to the various in-depth query functions described above, MongoDB also supports text search. Before searching for text, we need to create a text index for the key to be searched. Suppose we want to perform a text search on the title, we can do this first:

db.movie.ensureIndex({title:'text'})

Then we can perform a text search on the title, for example, find the title with "Gump":

db.movie.find({$text:{$search:"Gump"}}).pretty()

Note the $ sign in front of text and search.

In this example, the effect of text search is not very obvious. But assuming that the key we want to search is a long document, the convenience of this text search is revealed. MongoDB currently supports text search in 15 languages.

14. Regular Expressions

MongoDB also supports queries based on regular expressions. If you don’t know what regular expressions are, you can refer to Wikipedia . Here are a few simple examples. For example, to find bthe movie information whose title ends with:

db.movie.find({title:{$regex:'.*b$'}}).pretty()

Can also be written as:

db.movie.find({title:/.*b$/}).pretty()

Find movies with the title'Fight':

db.movie.find({title:/Fight/}).pretty()

Note that the above matches are all case-sensitive. If you want to make it case-insensitive, you can:

db.movie.find({title:{$regex:'fight.*b',$options:'$i'}}).pretty()

$iIt means insensitive. In this case, even lowercase fights can be searched.

15. Postscript

So far, the most basic content of MongoDB is almost introduced. If there is any omission, I will make it up later. If you have completed this introductory tutorial all the way, congratulations, you must be a persevering person.

Going through this document will not make you an expert in MongoDB (it would be weird if so). But if it can more or less reduce your time to get started, or make you realize "Hey, MongoDB is actually not that complicated", then the purpose of this tutorial will be achieved.

This document was written in a hurry, and errors are almost certain. If you find any errors or have any suggestions for this article, please email me (stevenslxie at gmail.com) or communicate directly on GitHub. Thank you very much.

Reprint statement

If you like this article, feel free to reprint it. But please
  • Mark the original author StevenSLXie;
  • Indicate the original link (https://github.com/StevenSLXie/Tutorials-for-Web-Developers/blob/master/MongoDB%20%E6%9E%81%E7%AE%80%E5%AE%9E%E8% B7%B5%E5%85%A5%E9%97%A8.md);
  • When possible, keep the text displayed beautifully. For example, please do not copy directly to blogs or the like with one click, because the display effect of the code may be very bad;
  • Please include this reprint statement;

Guess you like

Origin blog.csdn.net/sanhewuyang/article/details/107392970