Mongo Learning Records

Keywords: Database MongoDB SQL MySQL

Introduction

Recent projects use mongo logs for data statistics. Being obsessed with non-relational databases, I bought a copy of MongoDB Actual Warfare and studied it for a while. Record the learning notes and share them.

Get ready

I installed the latest version of Mono on my Linux server. Record another problem with the installation link.

Linux Installation mongo https://blog.51cto.com/136418...

I encountered a privilege problem when I wanted to see the state of the database.

> db.serverStatus()
{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { serverStatus: 1.0, lsid: { id: UUID(\"bbda7ede-9e92-492b-ae2f-f0f641fba261\") }, $db: \"admin\" }",
    "code" : 13,
    "codeName" : "Unauthorized"
}

Solution: https://www.cnblogs.com/alexz...

If we look at the above solution, we need to enter the mongo shell mode (admin) again by entering a command:

mongo -u 'admin' -p '123' --authenticationDatabase 'admin'

Basic concepts

mysql mongo explain
database database data base
table collection aggregate
row document File
column field field

Mongo stores data in BSON format, similar to JSON, as follows:

{
    "_id": ObjectId("5d399bb2b52d6dc8a4ff6b42"),
    "name": "pjjlt"
}

If the primary key is not specified, a _id (12 bytes in length) is generated by default. The generation rule is: 4 bytes timestamp + 3 bytes machine Id+2 bytes process Id+3 bytes random number.

Mongo operation

Basic operation

> show dbs #View all databases and usage
admin   0.000GB
config  0.000GB
local   0.000GB

> use pjjlt #Switch to the pjjlt library and find that it was not created
switched to db pjjlt

> db #View which database is currently being operated on
pjjlt

> db.myCollection.insert({"name":"pjjlt"}) #Insert a data into the myCollection collection of the pjjlt library (without this collection, create it)
WriteResult({ "nInserted" : 1 })

> show collections #View all collections under this library (pjjlt)
myCollection

> db.myCollection.find() #Query a collection of data
{ "_id" : ObjectId("5d399bb2b52d6dc8a4ff6b42"), "name" : "pjjlt" }

#The reason for the length of the article is not to demonstrate the following operation, but to explain it directly.
>db.myCollection.drop() #Delete a collection
>db.dropDatabase() #Delete a database
>db.serverStatus() #Look at the server status information. (Look at the engine right here. You can see that the default engine for mongo4 is wiredtiger.)
>db.stats() #Simple information in the current database allows you to see how many collections are in this database
>db.myCollection.stats() #View the basic information of a collection
>db.runCommand() #You can execute a function() method
>db.help() #View all operations at the database level
>db.myCollection.help() #View all operations at the collection level
>db.listCommands() #List all database commands

Data insertion

Data insertion can be divided into insert and save methods. Specific all methods, you can enter a piece of code, and then press the tab key twice to see.

#Two TAB keys, look at the following methods. Insert implements the following two methods: insert one or more
> db.myCollection.insert 
db.myCollection.insert(      db.myCollection.insertMany(  db.myCollection.insertOne(

#Insert a record
> db.myCollection.insert({"name":"haha"})
WriteResult({ "nInserted" : 1 })

#Insert multiple records and output more detailed information
> db.myCollection.insert([{"name":"hehe"},{"name":"heihei"}])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

#See how much data there is in the myCollection collection
> db.myCollection.count()
4

#Looking at the content again, _id is the primary key for automatic generation.
> db.myCollection.find()
{ "_id" : ObjectId("5d399bb2b52d6dc8a4ff6b42"), "name" : "pjjlt" }
{ "_id" : ObjectId("5d3a6bafd40e94efd747de7b"), "name" : "haha" }
{ "_id" : ObjectId("5d3a6c3fd40e94efd747de7c"), "name" : "hehe" }
{ "_id" : ObjectId("5d3a6c3fd40e94efd747de7d"), "name" : "heihei" }

#Take a look at the insertion function of save, which specifies _id
#Update if _id exists, insert if not, similar to insert
> db.myCollection.save({"name":"save0"})
WriteResult({ "nInserted" : 1 })

> db.myCollection.save([{"name":"save1"},{"name":"save2"}])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

> db.myCollection.find()
{ "_id" : ObjectId("5d399bb2b52d6dc8a4ff6b42"), "name" : "pjjlt" }
{ "_id" : ObjectId("5d3a6bafd40e94efd747de7b"), "name" : "haha" }
{ "_id" : ObjectId("5d3a6c3fd40e94efd747de7c"), "name" : "hehe" }
{ "_id" : ObjectId("5d3a6c3fd40e94efd747de7d"), "name" : "heihei" }
{ "_id" : ObjectId("5d3a927fb4d620841817e434"), "name" : "save0" }
{ "_id" : ObjectId("5d3a92a2b4d620841817e436"), "name" : "save1" }
{ "_id" : ObjectId("5d3a92a2b4d620841817e437"), "name" : "save2" }

Data modification

Data modification includes command save and update, in which update has the function of local update and replacement update.

#First look at the save method, specify _id, and modify it
> db.myCollection.save({"_id":ObjectId("5d3a92a2b4d620841817e437"),"name":"save3"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.myCollection.find()
{ "_id" : ObjectId("5d399bb2b52d6dc8a4ff6b42"), "name" : "pjjlt" }
{ "_id" : ObjectId("5d3a6bafd40e94efd747de7b"), "name" : "haha" }
{ "_id" : ObjectId("5d3a6c3fd40e94efd747de7c"), "name" : "hehe" }
{ "_id" : ObjectId("5d3a6c3fd40e94efd747de7d"), "name" : "heihei" }
{ "_id" : ObjectId("5d3a927fb4d620841817e434"), "name" : "save0" }
{ "_id" : ObjectId("5d3a92a2b4d620841817e436"), "name" : "save1" }
{ "_id" : ObjectId("5d3a92a2b4d620841817e437"), "name" : "save3" }

#Then look at the update method. Like insert, update implements the following two methods
> db.myCollection.update
db.myCollection.update(      db.myCollection.updateMany(  db.myCollection.updateOne(

Look at the update grammar

db.collection.update(
   <query>,   #The query condition of update, similar to the section after where of sql update statement
   <update>,  #update objects and some updated operators can also be understood as following the sql update statement set
   {
     upsert: <boolean>,  #Optionally, this parameter means that if there is no update record, whether to insert objNew, true is insert, default is false, no insert
     multi: <boolean>,   #Optionally, mongodb defaults to false, updates only the first record found, and if this parameter is true, updates all the records found on condition.
     writeConcern: <document>  #Optional, level of throwing exception
   }
)

Then back to the example, for illustration purposes, we create a new collection user

#Create a new document for a new collection
> db.user.insert({"username":"pjjlt","age":25})
WriteResult({ "nInserted" : 1 })
> db.user.find().pretty()
{
    "_id" : ObjectId("5d3aa1fcb4d620841817e438"),
    "username" : "pjjlt",
    "age" : 25
}

# ok, change the age of pjjlt to 18, and use the keyword $set. I will show you the effect of not using this keyword later.
> db.user.update({"_id" : ObjectId("5d3aa1fcb4d620841817e438")},{$set:{"age":18}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find().pretty()
{
    "_id" : ObjectId("5d3aa1fcb4d620841817e438"),
    "username" : "pjjlt",
    "age" : 18
}

#If you use $set as a local update, if you don't use it, replace the update. To differentiate, we've taken the new domain city as an example.
> db.user.update({"_id" : ObjectId("5d3aa1fcb4d620841817e438")},{"city":"SJZ"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find().pretty()
{ "_id" : ObjectId("5d3aa1fcb4d620841817e438"), "city" : "SJZ" }
#It was found that the original data had disappeared because it had been completely replaced.

Data deletion

Data deletion can use deleteMany, deleteOne, remove

# Two Tab s
> db.user.delete
db.user.deleteMany(  db.user.deleteOne(

# Delete no data
> db.user.deleteOne({"_id" : ObjectId("5d3aa1fcb4d620841817e438")})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.user.find().pretty()
> 

# Add a few more data
> db.user.find()
{ "_id" : ObjectId("5d3ab2f8b4d620841817e439"), "username" : "pjjlt", "age" : 25 }
{ "_id" : ObjectId("5d3ab2fdb4d620841817e43a"), "username" : "pjjlt1", "age" : 25 }
{ "_id" : ObjectId("5d3ab302b4d620841817e43b"), "username" : "pjjlt2", "age" : 25 }
{ "_id" : ObjectId("5d3ab322b4d620841817e43c"), "username" : "pjjlt3", "age" : 18 }

Remote grammar

db.collection.remove(
   <query>,    #Optional, Query Conditions
   {
     justOne: <boolean>,  #Optionally, set to true or 1, to delete only one document, set to false, to delete all matching documents, default to false
     writeConcern: <document> #Optional, level of throwing exception
   }
)

Let's go back to the example and delete it. Disk space needs to be freed manually

> db.user.remove({"age" : 25})
WriteResult({ "nRemoved" : 3 })
> db.user.find()
{ "_id" : ObjectId("5d3ab322b4d620841817e43c"), "username" : "pjjlt3", "age" : 18 }
#Manual release of disk space
> db.repairDatabase() 
{ "ok" : 1 }

Data query

Almost all businesses are related to queries.

Range query operator

operator describe
$lt less than
$gt greater than
$lte Less than or equal to
$gte Greater than or equal to

Prepare a large data set and add 1000 numbers to the numbers set

#The first three points are automatically generated and have no impact on the code. Please ignore them.
> for(i=0;i<1000;i++){
... db.numbers.save({num:i});
... }
WriteResult({ "nInserted" : 1 })

#Test one $lt, and the others are the same.
> db.numbers.find({"num":{$lt:5}})
{ "_id" : ObjectId("5d3ac7b7b4d620841817e43d"), "num" : 0 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e43e"), "num" : 1 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e43f"), "num" : 2 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e440"), "num" : 3 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e441"), "num" : 4 }

set operator

operator describe
$in If any parameter references a set, then matching
$all If all parameters are referenced in the collection and used in documents containing arrays, then matching
$nin If no parameters are in the reference set, match
#Insert a record
> db.tools.insert({tools:["AAA","BBB","CCC","DDD","EEE"]})
WriteResult({ "nInserted" : 1 })
#Check it out
> db.tools.find()
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ] }

#Find it through $in
> db.tools.find({tools:{
... $in:["AAA","FFF","ZZZ"]
... }
... })
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ] }

#all Search Test
> db.tools.find({tools:{ $all:["AAA","FFF","ZZZ"] } })
> db.tools.find({tools:{ $all:["AAA","BBB"] } })
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ] }

#$nin search test
> db.tools.find({tools:{ $nin:["AAA","BBB"] } })
> db.tools.find({tools:{ $nin:["ZZZ","YYY"] } })
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ] }

Boolean operator

operator describe
$ne Mismatched parameters
$not Mismatch result
$or A conditional match holds.
$nor All conditions do not match
$and All conditions match
$exists Judging whether an element exists
#Next, for the example above, use $ne
> db.tools.find({tools:{$ne:"AAA"}})
> db.tools.find({tools:{$ne:"ZZZ"}})
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ] }

#not looks like a condition reversal.
> db.tools.find({tools:{$not:{$in:["AAA"]}}})
> db.tools.find({tools:{$not:{$in:["ZZZ"]}}})
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ] }

#To demonstrate the following functions, add a new domain to the document you just saw
> db.tools.update({"_id" : ObjectId("5d3ad78eb4d620841817e825")},{$set:{"city":"SJZ"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.tools.find().pretty()
{
    "_id" : ObjectId("5d3ad78eb4d620841817e825"),
    "tools" : [
        "AAA",
        "BBB",
        "CCC",
        "DDD",
        "EEE"
    ],
    "city" : "SJZ"
}

#$or
> db.tools.find( {$or:[ {tools:{$in:["AAA"]}}, {"city":"BJ"} ]} )
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ], "city" : "SJZ" }

#All conditions of $nor do not match
> db.tools.find( {$nor:[ {tools:{$in:["ZZZ"]}}, {"city":"BJ"} ]} )
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ], "city" : "SJZ" }

#$and
> db.tools.find( {$and:[ {tools:{$in:["AAA"]}}, {"city":"BJ"} ]} )
> db.tools.find( {$and:[ {tools:{$in:["AAA"]}}, {"city":"SJZ"} ]} )
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ], "city" : "SJZ" }

#$exists
# Does tools Set Exist tools Domain
> db.tools.find({"tools":{$exists:true}})
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ], "city" : "SJZ" }
# Does the tools collection not exist in the tools domain?
> db.tools.find({"tools":{$exists:false}})
> 

Array operator

operator describe
$elemMatch If all the words provided are in the same subdocument, then match
$size If the subdocument array size is the same as the text value provided, then the matching
#Insert new documents into a new collection
> db.products.insert({addresses:[{name:"home",city:"sjz"},{name:"work",city:"bj"}]})
WriteResult({ "nInserted" : 1 })
> db.products.find().pretty()
{
    "_id" : ObjectId("5d3ae3763d2312bc3a0be84c"),
    "addresses" : [
        {
            "name" : "home",
            "city" : "sjz"
        },
        {
            "name" : "work",
            "city" : "bj"
        }
    ]
}

#elemMatch needs subdocuments
> db.products.find({addresses:{$elemMatch:{"name":"home","city":"sjz"}}})
{ "_id" : ObjectId("5d3ae3763d2312bc3a0be84c"), "addresses" : [ { "name" : "home", "city" : "sjz" }, { "name" : "work", "city" : "bj" } ] }

#size
> db.products.find({"addresses":{$size:1}})
> db.products.find({"addresses":{$size:2}})
{ "_id" : ObjectId("5d3ae3763d2312bc3a0be84c"), "addresses" : [ { "name" : "home", "city" : "sjz" }, { "name" : "work", "city" : "bj" } ] }

Sort Page Separator

operator describe
$sort Sort 1 in positive order; - 1 in retrospect
$limit How many bars are displayed?
$skip Jump too much data

Note that like MySQL, skip operates on large numbers very slowly and needs to be narrowed down in advance.

#Use the numbers collection
> db.numbers.find().sort({"num":-1}).skip(33).limit(9)
{ "_id" : ObjectId("5d3ac7b8b4d620841817e803"), "num" : 966 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e802"), "num" : 965 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e801"), "num" : 964 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e800"), "num" : 963 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e7ff"), "num" : 962 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e7fe"), "num" : 961 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e7fd"), "num" : 960 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e7fc"), "num" : 959 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e7fb"), "num" : 958 }

Other operators

operator describe
$where Execute arbitrary JavaScript to select documents
$regex Matching Regular Expressions
$mod[(quatient),(result)] Match if the dividend of the element matches the result
$type Matches if the element type matches the specified BSON type
$text Allow text search to be performed on fields that create text indexes
null It's not a keyword, don't add $, just look at the use
#Demonstrate mod and regex only
#Then use the numbers collection.
> db.numbers.find({"num":{$mod:[200,3]}})
{ "_id" : ObjectId("5d3ac7b8b4d620841817e440"), "num" : 3 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e508"), "num" : 203 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e5d0"), "num" : 403 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e698"), "num" : 603 }
{ "_id" : ObjectId("5d3ac7b8b4d620841817e760"), "num" : 803 }

#Search for all documents whose username begins with p using the user set just now
> db.user.find({"username":{$regex:/^p.*/}})
{ "_id" : ObjectId("5d3ab322b4d620841817e43c"), "username" : "pjjlt3", "age" : 18 }

#The use of null to search for documents that do not have this domain, or that domain is null
> db.user.find({"username":null})
> db.user.find({"username111":null})
{ "_id" : ObjectId("5d3ab322b4d620841817e43c"), "username" : "pjjlt3", "age" : 18 }

aggregate operation

The aggregation framework can be understood as GROUP BY in SQL. In order to invoke the aggregation framework, you need to define a pipeline. Each step output in the aggregation pipeline serves as the next input. Similar to the concept of flow.

operator describe
$project Specify the fields (items) in the output document
$match Select the fields to process, similar to find().
$limit Limit the number of documents passed to the next step
$skip Skip a certain number of documents
$unwind Expand the array to generate an output document for each array entry
$group Grouping documents by key
$skip Sort documents
$geoNear Select documents near a geographical location
$out Write the results of the pipeline into a collection
$redact Control access to specific data

Many of the above commands have the same functions as the query commands above, & dollar; geoNear (which seems interesting, similar to those algorithms in graph theory such as Dijster Stella and Freud, which can calculate the physical distance between coordinate points) and & dollar; redact have not been discussed much at first. & dollar; limit, & dollar; skip, & dollar; skip is too simple, as demonstrated above, and will not be repeated here. Take a look at the analogy between these commands and relational database SQL

SQL command Aggregate Command Operator
SELECT &dollar;project &dollar;group functions : &dollar;sum,&dollar;min,&dollar;avg,etc.
FROM db.collectionName.aggregate(...)
JOIN $unwind
WHERE $match
GROUP BY $group
HAVING $match

But the set command operator does not have to be written in the above order. For example, you can write $match for conditional filtering and then do other operations (in fact, it is often recommended to do so, after all, the first step is to filter most of the useless data).

#For illustration, create a new collection
> db.score.find()
{ "_id" : ObjectId("5d3bac2d78b22e869eb2fd26"), "name" : "pjjlt", "age" : 25, "city" : "sjz" }
{ "_id" : ObjectId("5d3bac5878b22e869eb2fd27"), "name" : "qex", "age" : 112, "city" : "london" }
{ "_id" : ObjectId("5d3bad9078b22e869eb2fd28"), "name" : "haha", "age" : 24, "city" : "sjz" }
{ "_id" : ObjectId("5d3bada078b22e869eb2fd29"), "name" : "heihei", "age" : 25, "city" : "bj" }

#Verify $match and $project
> db.score.aggregate([
... {$match:{age:{$lt:100}}}, //Conditional filtration
... {$project:{"_id":0}} //Do not display primary keys
... ])
{ "name" : "pjjlt", "age" : 25, "city" : "sjz" }
{ "name" : "haha", "age" : 24, "city" : "sjz" }
{ "name" : "heihei", "age" : 25, "city" : "bj" }

#The next group shows the average age of each city.
> db.score.aggregate([ {$group:{_id:"$city",avgAge:{$avg:"$age"}}} ])
{ "_id" : "bj", "avgAge" : 25 }
{ "_id" : "london", "avgAge" : 112 }
{ "_id" : "sjz", "avgAge" : 24.5 }

For &dollar; group, for raw data such as city and age, we need to add &dollar;, such as &dollar; city, &dollar; age before displaying, otherwise it will be null.

Also show commands that can be used in $group

command describe
$addToSet Create an array of unique values in a group
$first The first value in the group makes sense only with the prefix $sort
$last The last value in the group, only the prefix $sort, makes sense
$max Maximum value of a field in a group
$min Minimum value of a field in a group
$avg Average value of a field
$push Returns an array of all values in the group. No duplicate values
$sum Find the sum of all values in a group
#Come back and show the $out character, and the $out character is similar to the stream collector in Java 8 and must be last executed.
> db.score.aggregate([ {$group:{_id:"$city",avgAge:{$avg:"$age"}}} ,{$out:'aResult'}])

#Delete the data in the variable
> db.aResult.find()
{ "_id" : "bj", "avgAge" : 25 }
{ "_id" : "london", "avgAge" : 112 }
{ "_id" : "sjz", "avgAge" : 24.5 }

#Finally, $unwind, followed by the last tools Collection
> db.tools.find()
{ "_id" : ObjectId("5d3ad78eb4d620841817e825"), "tools" : [ "AAA", "BBB", "CCC", "DDD", "EEE" ], "city" : "SJZ" }

> db.tools.aggregate([
... {$project:{"_id":0}},
... {$unwind:"$tools"}
... ])
{ "tools" : "AAA", "city" : "SJZ" }
{ "tools" : "BBB", "city" : "SJZ" }
{ "tools" : "CCC", "city" : "SJZ" }
{ "tools" : "DDD", "city" : "SJZ" }
{ "tools" : "EEE", "city" : "SJZ" }

Like relational databases, data can be further processed when project ing. Optional functions include concat, toLower, toUpper string functions, add, mod, multiply arithmetic functions, date operators, logical operators, set operators, etc. There will be time to sum up later.

Atomicity

mongo is not as good at transaction processing as mysql. For example, when two different threads update (+1 operation), data may be overwritten. In particular, we introduce an atomic operation findAndModify(), which always finds that the modification submission is an atomic event, during which other threads will be rejected to query the data.
Of course, in order to protect data, lock can be considered at the business code level (such as java).

> db.score.find({"name":"qex"})
{ "_id" : ObjectId("5d3bac5878b22e869eb2fd27"), "name" : "qex", "age" : 112, "city" : "london" }

#Age of modifying qex
> db.score.findAndModify({
... query:{"name":"qex"},
... update:{ $inc:{"age":+3}}
... })
{
    "_id" : ObjectId("5d3bac5878b22e869eb2fd27"),
    "name" : "qex",
    "age" : 112,
    "city" : "london"
}
> db.score.find({"name":"qex"})
{ "_id" : ObjectId("5d3bac5878b22e869eb2fd27"), "name" : "qex", "age" : 115, "city" : "london" }

Summarize the update operators

Operator describe
$inc Change numbers based on given values
$set Set the field to the given value
$unset Cancel Settings Field
$rename Rename the value given by the field
$setOnInsert In upsert, set fields when inserting
$bit Perform bitwise update fields only
$ Locate subdocuments to be updated according to the query selector
$push Add values to arrays
$addToSet Add values to arrays, repeat and do not process
$pop Delete the first or last value from the array
$pull Delete the value matching the query condition from the array
$pullAll Delete multiple values from an array
$each Use it together from push and addToSet to manipulate multiple values
$slice Use push with each other to reduce the size of the updated array
$sort Use push with each and slice to sort subdocuments in an array
$isolated Isolate other operations and do not allow other operations to cross-update multiple documents

Indexes

Index classification

  1. unique index

Make sure that there is only one copy of the data in the set, such as the primary key, format:

> db.user.createIndex({username:1},{unique:true})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
  1. Sparse Index

Sparse indexing ensures that some documents do not contain this attribute and will not be filtered out. For example, building an index by phone number, but the number of documents in the collection is null, so these documents will not be taken into account when creating the index.

> db.user.createIndex({username:1},{sparse:true})
  1. Multi-key index

The index field is a number, such as the tools field in the tools collection, which means that queries on the index for any value of these arrays will be located on the document.

  1. Hash indices

The advantage of hash indexing is that entries on the index are evenly distributed.

db.user.createIndex({username:'hashed'})
  1. Geographical Location Index

Query documents near a location and store each document based on latitude and longitude.

Of course, the number of reference fields can also be divided into single-key index and composite index, similar to the behavior of mysql.

Index Management

  1. Indexing

Use createIndex(). Since the amount of data will cause the system to wait for a long time when indexing, it is possible to specify the background index (because a lot of data is needed, I did not experiment), and lead away from the clue, etc.

db.user.createIndex({username:'hashed'},{background: true})

Repeated index manipulation can generate large amounts of fragmentation in memory, and commands can be used to defragment (index newly created)

> db.user.reIndex()
{
    "nIndexesWas" : 2,
    "nIndexes" : 2,
    "indexes" : [
        {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "pjjlt.user"
        },
        {
            "v" : 2,
            "unique" : true,
            "key" : {
                "username" : 1
            },
            "name" : "username_1",
            "ns" : "pjjlt.user"
        }
    ],
    "ok" : 1
}
  1. View Index

To view the index of a collection, use getIndexes()

> db.user.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "pjjlt.user"
    },
    {
        "v" : 2,
        "unique" : true,
        "key" : {
            "username" : 1
        },
        "name" : "username_1",
        "ns" : "pjjlt.user"
    }
]
  1. Delete index
> db.user.dropIndex("username_1") #Names can be found when looking at the index
{ "nIndexesWas" : 2, "ok" : 1 }

engine

There are two main types: MMAPV1 and WiredTiger. Before version 2.6, only MMAPV1 was available. After version 3.0, there was WiredTiger, but by default it was still MMAPV1. This article uses version 4, which is the Wired Tiger engine by default. WiredTiger uses much less disk space than MMAPV1, requiring nearly one-seventh or eighth of that space. Remember to upgrade from the old version of mongo, import data, the original 20G data only last a single digit (a few specific G forgotten), startled, but also worried about losing data, the original engine changed. At the same time, the granularity of the lock is from database to document level, and the concurrency performance is improved a lot. In short, the new engine takes up less resources and has higher performance.

Reproduction and fragmentation

Replication: Replication is a method of distributing and maintaining data across multiple Mongo servers (nodes). MongoDB replicates data from one node to another and synchronizes changes. This type of replication is provided through a mechanism called a replicable set. The nodes in the cluster are configured to automatically synchronize data and to automatically tolerate disaster in the server. MongDB also has an old replication method: master-slave replication. Generally, when replicating data, when the data is synchronized to most of the nodes (more than 50%, for example, two of the three machines), the replication operation can be considered complete. The replicable set should protect at least three members, one of which can be a referee.

Fragmentation: Fragmentation is the process of partitioning large data sets into smaller manageable fragments. Simply put, a MongoDB server can't hold or process so much data (1, 2, 3, 4, 5, 6), so it divides the data into three smaller machines and maintains (1, 4) (2, 5) (3, 6) separately.

Reference resources

MongoDB Actual Warfare

Newbie Course https://www.runoob.com/mongod...

Posted by ahmadmunif on Sat, 27 Jul 2019 06:15:22 -0700