Friends, the next launch of the Databases course will take place tomorrow, so we held a traditional open lesson, a recording of which you can see here . This time we talked about the popular MongoDB database: we studied some of the subtleties, examined the basics of work, features and architecture. And also touched some User Cases.
The webinar was conducted by Ivan Remen , head of server development at Citimobil.
MongoDB Features
MongoDB is an open source document-oriented database management system that does not require a description of the table schema. It is classified as NoSQL and uses BSON (binary JSON). Scaled out of the box, written in C ++ and supports JavaScript syntax. No SQL support.
MongoDB has drivers for many popular programming languages (C, C ++, C #, Go, Java, JavaScript, Perl, PHP, Python, Ruby, etc.). There are also unofficial and community-supported drivers for other programming languages.
Well, let's look at the basic commands that may be useful.
So, to deploy MongoDB in Docker , we write:
docker run -it --rm -p 127.0.0.1:27017:27017 --name mongo-exp-project mongo docker exec -it mongo-exp-project mongo
Thus, the MongoDB
client starts up :
Now let's write the traditional
Hello World :
print (“Hello world!”)
After that,
run the loop :
As you can see, we have
regular JS in front of us,
and MongoDB is a full-fledged JavaScript interpreter .
When to use MongoDB?
There is a story that the average startup in Silicon Valley is the man who opened the book “HTML for Dummies” a week ago. Which stack will he choose? You must admit that it is very convenient for him when he has JavaScript in his browser for obvious reasons, Node.js is spinning on the server, and JavaScript is also in the database. This is point number 1.
Secondly, there is an
excellent presentation by Peter Zaitsev, one of the best database experts in Russia. In it, Peter talks about MySQL and MongoDB, focusing on when and what is best to use.
Thirdly, I want to emphasize that MongoDB is characterized by good
scalability - and this is one of the key features of the database. If you don’t know in advance what the load will be, MongoDB is perfect. In addition, it supports such patterns out of the box as
sharding and
replication , and all this is made quite transparent, that is, it is very convenient to work.
Regarding
terminology in MongoDB, then:
- bases are bases (schemes, a totality of tables);
- in MongoDB there is such a thing as a collection - it is an analog of a table and a set of documents that, according to the logic of things, should be connected;
- documents are an analog of a line.
Database creation and simple queries
To create a database, you just need to start using it:
use learn
Now let's make a small insert of the document. Let it be, for example, a unicorn named Aurora:
db.unicorns.insert({name: 'Aurora', gender: 'f', weight: 450})
db is a global object for accessing the database, that is, in fact, the “monga" itself. For sharding,
sh is used; for replication,
rs is used .
What commands does the
db object have:
So, back to our team, as a result of which the console will report that one row is inserted:
The word
unicorns
in the
db.unicorns.insert({name: 'Aurora', gender: 'f', weight: 450})
means a collection. Please note here that we did not describe or create the collection, but simply wrote 'unicorns', made insert, and we got a collection.
And so we can
get all our collections :
db.getCollectionNames()
Well and so on. We can
insert another collection:
And now we’ll request a
complete collection (we recall that in our case the database already contains information about two unicorns with the same name):
db.unicorns.find()
Please note, here is our JSON (there is a name, gender, weight, some unique identifier of the object):
Now let's insert a couple more unicorns with the same name:
db.unicorns.insert({name: 'Leto', gender: 'm', home: 'Arrakeen', worm: false}) db.unicorns.insert({name: 'Leto', gender: 'm', home: 'Arrakeen', worm: false})
And let's see what happened:
As you can see, we have additional fields:
home and
worm , which Aurora does not have.
Add a few more unicorns:
db.unicorns.insertMany([{name: 'Horny', dob: new Date(1992,2,13,7,47), loves: ['carrot','papaya'], weight: 600, gender: 'm', vampires: 63}, {name: 'Aurora', dob: new Date(1991, 0, 24, 13, 0), loves: ['carrot', 'grape'], weight: 450, gender: 'f', vampires: 43}, {name: 'Unicrom', dob: new Date(1973, 1, 9, 22, 10), loves: ['energon', 'redbull'], weight: 984, gender: 'm', vampires: 182}, {name: 'Roooooodles', dob: new Date(1979, 7, 18, 18, 44), loves: ['apple'], weight: 575, gender: 'm', vampires: 99}])
So, we inserted four more objects using JavaScript:
In your opinion, in which databases is it more convenient to store passport data: in relational databases or in mong?
The answer is obvious - in mong, and the above example shows it well. It is no secret that KLADR is a pain in the Russian Federation. And the monga very well falls on the addresses, because you can specify everything as an array, and it will be much easier to live. And this is a good
User Case for MongoDB .
Add more unicorns:
db.unicorns.insert({name: 'Solnara', dob: new Date(1985, 6, 4, 2, 1), loves:['apple', 'carrot', 'chocolate'], weight:550, gender:'f', vampires:80}); db.unicorns.insert({name:'Ayna', dob: new Date(1998, 2, 7, 8, 30), loves: ['strawberry', 'lemon'], weight: 733, gender: 'f', vampires: 40}); db.unicorns.insert({name:'Kenny', dob: new Date(1997, 6, 1, 10, 42), loves: ['grape', 'lemon'], weight: 690, gender: 'm', vampires: 39}); db.unicorns.insert({name: 'Raleigh', dob: new Date(2005, 4, 3, 0, 57), loves: ['apple', 'sugar'], weight: 421, gender: 'm', vampires: 2}); db.unicorns.insert({name: 'Leia', dob: new Date(2001, 9, 8, 14, 53), loves: ['apple', 'watermelon'], weight: 601, gender: 'f', vampires: 33}); db.unicorns.insert({name: 'Pilot', dob: new Date(1997, 2, 1, 5, 3), loves: ['apple', 'watermelon'], weight: 650, gender: 'm', vampires: 54}); db.unicorns.insert({name: 'Nimue', dob: new Date(1999, 11, 20, 16, 15), loves: ['grape', 'carrot'], weight: 540, gender: 'f'}); db.unicorns.insert({name: 'Dunx', dob: new Date(1976, 6, 18, 18, 18), loves: ['grape', 'watermelon'], weight: 704, gender: 'm', vampires: 165});
Now pay attention to the documents. We have whole objects stored as a
dob . And there is also information that the unicorn loves, and not everyone has this data. Thus, inside is a
full array .
By the way, for a more beautiful output, you can call the
.pretty()
method at the end of the search command:
If you need to get
information about the last error , use the following command:
db.getLastError()
This can be done after each insertion, or you can configure Write Concern. It is better to read about it in the
official documentation , which, by the way, is very informative in mong. By the way, there is also a
good article on this subject on Habr.
Moving on to more complex queries
Request for exact field value: db.unicorns.find({gender: 'm'})
By writing such a request, we get in the output on the console a list of all male unicorns.
You can also execute a
query at once in several fields : by sex and by weight:
Above, pay attention to the special
$ gt selector , which allows you to display all male unicorns weighing more than 700.
You can check
if the field exists at all :
db.unicorns.find({vampires: {$exists: false}})
Or so:
db.unicorns.find({'parents.father': {$exists: true}})
The following command displays unicorns whose
names begin with the letters A or a: db.unicorns.find({name: {$regex: "^[Aa]"}})
Now let's
look at an array search . Question number 1: what will this command output:
db.unicorns.find({loves:'apple'})
That's right: everyone who loves apples.
The following command will return only the unicorn data that contains
only apples and watermelons: db.unicorns.find({loves:[ "apple", "watermelon" ]})
And one more command:
db.unicorns.find({loves:[ "watermelon", "apple" ]})
In our case, it will not return anything, since when we pass an array, the first element is compared with the first, the second with the second, etc. That is, the array must also coincide
in the positions of these values.
And here's what an
array search looks like
using the OR operator :
The following example will show us a
search using the $ all operator . And here the sequence is already unprincipled:
We can also
search by the size of the array:But what if we want to find an array that is larger than one? There is a
$ where operator for this, with which you can write more complex things:
db.unicorns.find({$where: function() { return this.loves && (this.loves.length > 1) } })
By the way, if you want to practice,
here is a file with commands.
Cursor Features
Let's digress a little and say a few words about the features of monga:
- find () and other operations do not return data - they return the so-called "cursor";
- what we see as the data is printed is the work of the interpreter.
By typing
db.unicorns.find without parentheses, we get a hint:
We continue to fulfill requests
There is also the $ in operator: db.unicorns.find({weight: {$in: [650, 704]}})
Now let's talk about update . For example, let's change the weight of the unicorn Roooooodles:
db.unicorns.update({name: "Roooooodles"}, {weight: 2222})
As a result of our actions, the document
will be completely updated , and only one specified field will remain in it:
That is, the only thing that remains with our object is the weight of 2222 and, of course, id.
You can fix this with
$ set :
db.unicorns.update({_id: ObjectId("5da6ea4d9703b8be0089e6db")}, {$set: { "name" : "Roooooodles", "dob" : ISODate("1979-08-18T18:44:00Z"), "loves" : [ "apple" ], "gender" : "m", "vampires" : 99}})
It is also possible to
increment values :
There is also
upsert - a combination of update and insert:
And here is how to
select fields :
It remains to add a few words about
skip and
limit :
Colleagues, that’s all, if you want to know the details,
watch the entire video . And do not forget to leave your comments!