In this article you can find some useful commands for MQL (Mongo Query Language)*
Content:
- Importing, Exporting
- Database and collection operations
- Creating and manipulating document
- Advanced CRUD operation
- Aggregation operations
- Indexing
Import/export operations
For Bson import/export use:
- mongorestore
- mongodump
Example:
mongorestore --uri "mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --drop dump
mongodump --uri "mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies"`
For Json import/export use:
- mongoimport
- mongoexport
Example:
mongoimport --uri="mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --drop sales.json
mongoexport --uri="mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --collection=sales --out=sales.json
Database and collection operations
- Show the list of databases
show dbs
- Switch to use specified database
use my_database
- Show the list of collections
show collections
- Create a new collection with name 'users'
db.createCollection("users")
- Drop 'users' collection
db.users.drop()
Creating and manipulating document
You can try examples on collection 'users' with such structure:
{
"name": "Alex",
"age": 10,
"posts": [{
"name": "Post1"
}, {
"name": "Post2"
}]
}
- Find all documents with field "name" equal to "Alex"
db.users.find({"name": "Alex"})
- Get a random document from the collection
db.users.findOne()
- Insert document into users collection
db.users.insert({
"_id" : ObjectId("56d61033a378eccde8a8354f"),
"name" : "Peter",
"birth_date" : "Feb 20 1995"
})
- update document.
db.users.updateOne({<query to locate>]}, {<update>})
For the first user which has a name "Alex" will set age = 20
db.users.updateOne({"name": "Alex"}, {"age": 20})
- Upsert - hybrid operation of update and insert
db.users.updateOne({<query to locate>]}, {<update>}, {"upsert": true})
- For user with name "Alex" will update age, but if such user doesn't exists, will insert new document with name = Alex and age = 20
db.users.updateOne({"name": "Alex"}, {"age": 20}, {"upsert": true})
- Update all documents in the 'users' collection where the 'name' field is equal to "Alex" by adding 1 to the current value of the "age" field.
db.users.updateMany({ "name": "Alex" }, { "$inc": { "age": 1 } })
- Update one document in the 'users' collection where the "name" is
Alex
and the "age" field is 20 , by adding a document element to the "posts" array.
db.users.updateOne({ "name": "Alex", "age": 20 },
{ "$push": { "posts": { "name": "Post3"}
}
})
- Delete all the documents that have "age" field equal to 10
db.users.deleteMany({ "age": 20 })
- Delete one document that has "age" field equal to 20.
db.users.deleteOne({ "age": 20 })
Advanced CRUD operators
For executing queries you can use such collection structure
[
{
"name": 'Alex',
"age": 20,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] },
{
"name": 'Peter',
"age": 30,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] },
{
"name": 'Andrew',
"age": 18,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] }
]
Comparison operators
Here the table of comparison operators:
Operator | Description |
---|---|
$eq | Matches if value is equal to the given value |
$ne | Matches if value is not equal to the given value |
$lt | Matches if values are less than the given value. |
$gte | Matches if values are greater or equal to the given value. |
$lte | Matches if values are less or equal to the given value. |
$in | Matches any of the values in an array. |
- Find all documents where the "age" less than or equal to 20:
db.users.find({ "age": { "$lte" : 20 }}).pretty()
will return:
{ "_id": ObjectId("611a79b8f30c577098be1de6"),
"name": 'Andrew',
"age": 18,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] }
{ "_id": ObjectId("611a7051f30c577098be1de1"),
"name": 'Alex',
"age": 20,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] }
- Find all documents where the "age" less than or equal to 20 but "name" not equal to 'Alex':
db.users.find({ "age": { "$lte" : 20 },
"name": { "$ne": "Alex" } }).pretty()
will return the single document:
{ "_id": ObjectId("611a79b8f30c577098be1de6"),
"name": 'Andrew',
"age": 18,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] }
Logic operators
Operator | Description |
---|---|
$and | Joins query clauses with a logical AND returns all documents that match the conditions of both clauses. |
$not | Inverts the effect of a query expression and returns documents that do not match the query expression. |
$nor | Joins query clauses with a logical NOR returns all documents that fail to match both clauses. |
$or | Joins query clauses with a logical OR returns all documents that match the conditions of either clause. |
Example:
db.users.find({ "$and": [ { "$or" :[ { "age": 20 },
{ "name": "Peter" }
] },
{ "$or" :[ { "age": 30 },
{ "name": "Andrew" } ] }
]}).pretty()
will return
{ "_id": ObjectId("611a79acf30c577098be1de4"),
"name": 'Peter',
"age": 30,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' }, { "name": 'Post3' } ] }
Expressive query operators
For examples use such collection structure:
{ _id: ObjectId("611a79acf30c577098be1de4"),
name: 'Peter',
age: 30,
posts: [ { name: 'Post1' }, { name: 'Post2' } ],
postsCount: 5,
videoCount: 5 }
{ _id: ObjectId("611a79b8f30c577098be1de6"),
name: 'Andrew',
age: 18,
posts: [ { name: 'Post1' }, { name: 'Post3' } ],
postsCount: 6,
videoCount: 3 }
{ _id: ObjectId("611a7051f30c577098be1de1"),
name: 'Alex',
age: 20,
posts: [ { name: 'Post2' }, { name: 'Post3' } ],
postsCount: 5,
videoCount: 7 }
$expr - allow the use of aggregation expressions within the query language
- Find all documents where the count of videous and possts are equal:
db.users.find({ "$expr": { "$eq": [ "$postsCount", "$videoCount"] }
}).count()
will return
1
Array operators and projection
Projection allows displaying not the whole document, but specified fields only.
Find all documents with exactly 2 posts which include all the posts names listed in the query array, and display their name:
db.users.find({ "posts":
{ "$size": 2, "$all": [ {"name": "Post1"}, {"name":"Post2"} ] } },
{"name": 1}).pretty()
will return result
{ _id: ObjectId("611a79acf30c577098be1de4"), name: 'Peter' }
Well, that is good, but what if we want to get document without "_id", only user name ?
We can modify projection like this:
db.test.find({ "posts":
{ "$size": 2, "$all": [ {"name": "Post1"}, {"name":"Post2"} ] } },
{"name": 1, "_id": 0}).pretty()
and result will be:
{ name: 'Peter' }
Query Arrays and sub documents
For examples use such collection structure
[
{ "_id": ObjectId("611a79acf30c577098be1de4"),
"name": 'Peter',
"age": 30,
"posts": [ { "name": 'Post1' }, { "name": 'Post2' } ] },
{ "_id": ObjectId("611a79b8f30c577098be1de6"),
"name": 'Andrew',
"age": 18,
posts: [ { "name": 'Post1' }, { "name": 'Post3' } ] },
{ "_id": ObjectId("611a7051f30c577098be1de1"),
"name": 'Alex',
"age": 20,
"posts": [ { "name": 'Post2' }, { "name": 'Post3' } ] }
]
- Find all documents, which have in an array "posts" document with "name" equal to "Post1"
db.users.find({ "posts.name": "Post1" },
{ "name": 1 }).pretty()
will return
{ "_id": ObjectId("611a79acf30c577098be1de4"), "name": 'Peter' }
{ "_id": ObjectId("611a79b8f30c577098be1de6"), "name": 'Andrew' }
The same query as previous but with $elemMatch operator
db.users.find({ "posts":
{ "$elemMatch": { "name": "Post1" } } },
{ "name": 1 }).pretty()
will return the same result
{ "_id": ObjectId("611a79acf30c577098be1de4"), "name": 'Peter' }
{ "_id": ObjectId("611a79b8f30c577098be1de6"), "name": 'Andrew' }
also, you can use count()
db.users.find({ "posts.name": "Post1" },
{ "name": 1 }).count()
or
db.users.find({ "posts":
{ "$elemMatch": { "name": "Post1" } } },
{ "name": 1 }).count()
Result:
2
Aggregation
Cursor methods
- Get the number of documents where name equal to "Alex"
db.users.find({ "name": "Alex" }).count()
- The same as db.users.find(), but with pretty formatting
db.users.find({"name": "Alex"}).pretty()
- Allow sorting documents by the specified field. "name": -1 means descending. Yoy also can specify 1 - ascending.
db.users.find().sort({ "name": -1 })
- limit() Command allow you get specified amount of documents instead all of them
db.users.find().limit(1)
Aggregation framework
Aggregation framework is a simplest form, another way then MQL to query data in mongo DB.
For examples use such collection structure.
{ _id: ObjectId("611a79acf30c577098be1de4"),
name: 'Peter',
age: 30,
posts: [ { name: 'Post1' }, { name: 'Post2' } ],
postsCount: 5,
videoCount: 5 }
{ _id: ObjectId("611a79b8f30c577098be1de6"),
name: 'Andrew',
age: 18,
posts: [ { name: 'Post1' }, { name: 'Post3' } ],
postsCount: 6,
videoCount: 3 }
{ _id: ObjectId("611a7051f30c577098be1de1"),
name: 'Alex',
age: 20,
posts: [ { name: 'Post2' }, { name: 'Post3' } ],
postsCount: 5,
videoCount: 7 }
Find all documents that have Wifi as one of the amenities. Only include price and address in the resulting cursor.
MQL example:
db.users.find({ "name": "Alex" },
{ "name": 1, "age": 1, "postsCount": 1,"_id": 0 }).pretty()
Aggregation framework example:
db.users.aggregate([
{ "$match": { "name": "Alex" } },
{ "$project": { "name": 1,
"age": 1,
"postsCount": 1,
"_id": 0 }}]).pretty()
both return the same result:
{ name: 'Alex', age: 20, postsCount: 5 }
Indexes
Allows making queries more efficient. It's better to create indexes for those fields, which often using in the queries, for example:
db.users.find().sort({ "name": -1 })
db.users.find({"name": "Alex"})
Here field "name" is a good candidate for indexing.
Index types:
- Single field index
db.users.createIndex({"name": -1})
- Compound index - index for multiple fields
db.users.createIndex({"name": 1}, "last_name": 1)
Index types table
type | description |
---|---|
Single index | contains only one field |
Compound index | contains multiple fields |
Multikey indexes | indexes against array fields |
Text index | MongoDB provides text indexes to support text search queries on string content |
Wildcard index | Since MongoDB supports dynamic schemas, applications can query against fields whose names cannot be known in advance or are arbitrary. |
2dsphere index | supports queries that calculate geometries on an earth-like sphere |
If you like an article, you can support me
Top comments (0)