Getting started with MongoDB (features, usage scenarios, command line operations, SpringData-MongoDB)

Today we will use this blog to understand the architecture of MongoDB, command line operations and using SpringData-MongoDB in JAVA to operate MongoDB.

If you don’t have it installed, you can read this article (59 messages) Open source document database – MongoDB (installation)_Everything will always end up in a boring blog – CSDN blog , install MongoDB.

Let’s take a look at the data characteristics of MongoDB:

  1. The amount of data storage is large, even massive
  2. High response speed for data reading and writing
  3. Data security is not high and there is a certain range of error.

Seeing this, some friends may ask? Oops, let me go, is this MongoDB so awesome?

Then why is it so awesome? Let's take a look at its features.

1. Features

1.1 Data storage

The first feature of MongoDB: data storage

MongoDB uses memory + disk to complete data storage. The interaction between the client and MongoDB is divided into two parts.

image-20230112145419358

The client's operation first operates on the memory. So we know that the operating speed of the memory is the same as the speed of operating the disk, so the memory operation is definitely much faster than the disk operation speed.

So, if your memory is large enough, if I want to query from mengoDB, I can query directly from the memory, avoiding disk query.

Of course, if there is no memory, it will read it from the disk and return it to the client.

The above is about querying, and writing is also written into the memory first, and then returned to the client. Therefore, if you want to write, the memory is directly operated, so its efficiency is extremely high.

Then you may have questions. Now that the data is in the memory, if I restart the server, won't all the data disappear?

In this regard, MongoDB will use the operating system mechanism to automatically map the data in the memory to the disk. However, it will have a time rule and will write every 60 seconds.

Is there any problem with this?

There must be some. If the data has been written into the memory but has not yet been synchronized to the disk, and the power is out, does that mean that the data for the past 60 seconds has been lost? This also explains why MongoDB is more efficient because it operates on memory.

Then there is the problem of data loss in MongoDB? Because it involves data synchronization between memory and disk.

In order to solve this problem, MongoDB optimized the structure in later versions.image-20230112150656101

It divides the memory into two parts, one is the representative log and the other is the real business data. The same disk is also divided into two parts, one is the log file and the other is the business data file.

When the client sends a request to the memory, it must first record your operation log, and then write it to the memory part of the business data. The memory part of the log will be synchronized with the log part on the disk for 10 milliseconds.

The business data part will be synchronized after 60 seconds.

What are the benefits of this design? First of all, if the server is powered off again, the time it takes to synchronize data between logs is shorter than the previous one. After all, it has been shortened from 60 to 10 milliseconds, so all operation logs will be synchronized to the log file without interruption.

Although the business data may be lost for 60 seconds, it does not matter. The log file will be released. When the server restarts, it will parse the content in the log file and the content of the business data and compare the two.

The lost content is too compensated for storage in files, but no matter how hard mongoDB tries, data will be lost at a certain interval.

1.2 High scalability

The scalability of mongoDB is achieved with the help of built-in data sharding. When we use MongoDB, this often happens. Due to the limited storage capacity of mongoDB's hard disk, redundant data may not be able to be stored.

What should we do at this time? With the built-in data sharding, we can connect multiple mongoDB servers together in series, and each machine stores a part. In this way, the amount of data storage is large.

Using mongDB's built-in data sharding can easily store massive data content, which also lays the foundation for massive data. Although MySQL also supports data sharding, it only needs to use third-party services and components to implement it, and the implementation cost may be higher.

2. Comparison

After reading the above introduction to the characteristics of mengoDB, you may be a little confused. Let me go, redis is already very powerful, and mysql is also very good. Now there is another mongoDB. How should I choose?

  1. Comparison with Redis
    1. Redis is a pure memory database. If insufficient memory triggers the elimination strategy, then this part of the content will be really lost!
    2. Structured storage format (Bson) for easy expansion.
    3. mongDB can query based on a certain field, but this is not what Redis is good at.
  2. Compared with MySQL
    1. MongoDB does not support transactions and multi-table operations; for example, if a user's account needs to satisfy the simultaneous success/failure of multiple operations, then using mongDB is not appropriate.
    2. MongoDB supports dynamic field management. Example: There are two fields in the data. You save one and it becomes three. When you save four, the number and type of fields can be flexibly changed, but once the fields are defined in MySQL, it is difficult to modify them. .

Compare from the perspective of query efficiency:

Redis -> MongoDB -> MySQL

3. Usage scenarios

  1. Game equipment data, game prop data
    1. Features: high frequency of modification
  2. Logistics industry data
    1. Features: geographic location information, massive data
  3. Live broadcast data, reward data, fan data
    1. Features: large amount of data, high frequency of modification
  4. log data
    1. Features: huge amount of data, variable structure

Are the above applicable scenarios for mengoDB? If you encounter similar scenarios in actual projects, you may choose to store data in mengoDB.

4. MongoDB architecture and terminology

MongoDB is the non-relational database that is most similar to a relational database. The reason why it is said this is because its architecture is similar to MySQL.

Let's get a preliminary understanding of MongoDB's architecture through comparison.

SQL terms/concepts MongoDB terms/concepts explain
database database database
table collection Database table/collection
row document a piece of data in the table
column field Data fields/domains
index index index
table joins Table join, MongoDB does not support
primary key primary key Primary key, MongoDB automatically sets the _id field as the primary key

image-20230117140726215

Knowing the architecture of MongoDB, let's take a look at its data structure.

MongoDB uses Bson to store data (Binary JSON), a Json-like data format.

Let's take a look at how a piece of data is displayed in the form of BSON. Let's compare it through MySQL.

MySQL:

image-20230117141046130

MongoDB:

image-20230117141148121

5. MongoDB command line operation

After understanding the basic concepts of MongoDB, we can get started with MongoDB.

5.1 Database and table operations

1. Query all databases.

show dbs

2. Switch the database through the use keyword.

use 切换的数据库

image-20230117142228141

3. Create a database: In MongoDB, the database is automatically created. Use use to switch to a new database and insert data to automatically create the database.

use testdb2

Now query the database, and the database does not appear.

image-20230117142703713

Insert data.

db.user.insert({id:1,name:'zhangsan'})

image-20230117142810998

Inquire now.

image-20230117143008626

4. Check the table.

show tables

image-20230117143142995

show collections

image-20230117143805152

5. Delete the collection (table).

db.user.drop()

image-20230117143928068

6. Delete the database (you need to switch to the data to be deleted first)

use 要切换的数据库

delete

db.dropDatabase() 

5.2 New data

1. Insert data (syntax: db.table name.insert(json string))

db.user.insert({id:1,username:'zhangsan',age:20})

2. Query data

db.user.find()

image-20230117144737976

You may have questions here, why is there an underscore id? This is because MongoDB itself has a default primary key ID, which is this _id.

5.3 Update data

The update() method is used to update an existing document. The syntax format is as follows:

db.collection.update(
   <query>,
   <update>,
   [
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   ]
)

Parameter Description:

  • query : update query conditions, similar to where behind the sql update query.
  • update : update object and some update operators (such as , ,, inc.$set), etc., can also be understood as the following set in the sql update query
  • upsert : Optional, this parameter means whether to insert objNew if there is no updated record, true means insert, the default is false, not insert.
  • multi : optional. The default value of mongodb is false. Only the first record found is updated. If this parameter is true, all multiple records found according to the conditions are updated.
  • writeConcern : Optional, the level at which the exception is thrown.

Case:

db.user.update({
    
    id:1},{
    
    $set:{
    
    age:22}}) 

image-20230117145525202

To update non-existing data, no new data will be added by default.

db.user.update({id:2},{$set:{sex:1}})

image-20230117150134844

5.4 Deletion of data

Delete data through the remove() method, the syntax is as follows:

db.collection.remove(
   <query>,
   {
    
    
     justOne: <boolean>,
     writeConcern: <document>
   }
)

Parameter Description:

  • query : (optional) Conditions for deleted documents.
  • justOne : (optional) If set to true or 1, only one document will be deleted. If this parameter is not set, or the default value of false is used, all documents matching the condition will be deleted.
  • writeConcern : (optional) The level at which the exception is thrown.

Code demo:

First we insert the data first.

db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})

Delete data with age 22, only one.

db.user.remove({age:22},true)

Delete all data.

db.user.remove({})

5.5 Query data

The syntax format of MongoDB query data is as follows:

db.user.find([query],[fields])
  • query : optional, use query operator to specify query conditions
  • fields : Optional, use the projection operator to specify the returned keys. To return all key values ​​in the document when querying, just omit this parameter (omitted by default).

Condition query:

operate Format example Similar statements in RDBMS
equal {<key>:<value>} db.col.find({"by":"一切总会归于平淡"}).pretty() where by = '一切总会归于平淡'
less than {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
less than or equal to {<key>:{$lte:<value>}} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
more than the {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
greater than or equal to {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
not equal to {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50

Code demo:

Insert data:

db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})

1. Query all data:

db.user.find() 

image-20230126140911445

2. Only query the id and username fields.

db.user.find({},{id:1,username:1})

image-20230126141024948

3. Query the number of data items

db.user.find().count()

image-20230126141125038

4. Query the data with id 1

db.user.find({id:1})

image-20230126141153811

5. Query data whose age is less than or equal to 21

db.user.find({age:{$lte:21}})

image-20230126141330900

6. Query id=1 or id=2

db.user.find({$or:[{id:1},{id:2}]})

image-20230126141429638

7. Paging query: Skip() skips a few items, limit() queries the number of items

Skip 1 piece of data and query 2 pieces of data

db.user.find().limit(2).skip(1)

image-20230126141519851

Sort by ID in reverse order, -1 is reverse order, 1 is forward order

db.user.find().sort({id:-1})

image-20230126141557350

5.6 Index

In order to improve query efficiency, indexes are also supported in MongoDB.

Create index.

db.user.createIndex({'age':1})

image-20230126141926089

Note: 1: Ascending index - 1: Descending index

View index.

db.user.getIndexes()

image-20230126142008926

5.7. Execution plan

MongoDB query analysis can ensure whether our proposed indexes are effective and is an important tool for query statement performance analysis.

Insert 1000 pieces of data.

for(var i=1;i<1000;i++)db.user.insert({id:100+i,username:'name_'+i,age:10+i})

View the execution plan.

db.user.find({age:{$gt:100},id:{$lt:200}}).explain()

image-20230126142758779

Tested without using indexes.

db.user.find({username:'zhangsan'}).explain()

image-20230126142847549

image-20230126143051206

winningPlan: best execution plan;
"stage": "FETCH", #Query method, common ones include COLLSCAN/full table scan, IXSCAN/index scan, FETCH/retrieve documents based on index, SHARD_MERGE/merge shard results, IDHACK/ Query against _id

6、SpringData-Mongo

After simply understanding the basic commands and indexes of MongoDB, we will get to the focus of this blog.

We need to operate MongoDB in the SpringBoot program. When it comes to operating MongoDB with JAVA code, there are no more than two ways.

  1. Using the official driver is similar to using the most basic JDBC driver to operate mysql.
  2. Use Spring Data Mongo DB provided by Spring Data.

Using the first method is too troublesome (I like to be lazy), so we use the second method.

Spring-data supports MongoDB. Using spring-data-mongodb can simplify the operation of MongoDB and encapsulate the underlying mongodb-driver.

Address: https://spring.io/projects/spring-data-mongodb

Using Spring-Data-MongoDB is very simple and only requires the following steps:

6.1 Environment setup

6.1.1 Create project

image-20230126144234631

Don't choose springBoot version 3.0 or above. If your jdk version is 17 or above, I didn't say it.

image-20230126144335955

6.1.2 Writing YML files

spring:
  data:
    mongodb:
      uri: mongodb://192.168.136.160:27017/testdb2

6.2 Complete basic operations

The first step is to write entity classes.

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(value = "tb_person") // 指定实体类和MongoDB集合的映射关系
public class Person {
    
    

    @Id
    private ObjectId id;

    @Field("name")
    private String name;

    @Field("age")
    private int age;

    @Field("address")
    private String address;

}

The second step is to complete the CRUD operation through MongoTemplate.

Here it is demonstrated directly in the test class.

	/**
     * 注入模板对象
     */
    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * 增加
     */
    @Test
    public void testSave() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            Person person = new Person();

            //ObjectId.get():获取一个唯一主键字符串
            person.setId(ObjectId.get());
            person.setName("张三" + i);
            person.setAddress("北京顺义" + i);
            person.setAge(18 + i);

            mongoTemplate.save(person);
        }
    }

image-20230126200357264

Check all.

/**
 * 注入模板对象
 */
@Resource
private MongoTemplate mongoTemplate;


/**
 * 查询所有
 */
@Test
public void testFindAll() {
    
    
    List<Person> list = mongoTemplate.findAll(Person.class);
    for (Person person : list) {
    
    
        System.out.println(person);
    }
}

image-20230126200537409

Query all people whose age is less than 20.

/**
 * 注入模板对象
 */
@Resource
private MongoTemplate mongoTemplate;


/**
 * 查询年龄小于20的所有人
 */
@Test
public void testFind() {
    
    

    Query query = new Query(Criteria.where("age").lt(20)); //查询条件对象
    //查询
    List<Person> list = mongoTemplate.find(query, Person.class);

    list.forEach(System.out::println);
}

image-20230126200822318

Paging query.

/**
 * 注入模板对象
 */
@Resource
private MongoTemplate mongoTemplate;


/**
 * 分页查询
 */
@Test
public void testPage() {
    
    
    Criteria criteria = Criteria.where("age").lt(30);
    //1、查询总数
    Query queryCount = new Query(criteria);
    long count = mongoTemplate.count(queryCount, Person.class);
    System.out.println(count);
    //2、查询当前页的数据列表, 查询第二页,每页查询2条
    Query queryLimit = new Query(criteria)
            //设置每页查询条数
            .limit(2)
            //开启查询的条数 (page-1)*size
            .skip(2);
    List<Person> list = mongoTemplate.find(queryLimit, Person.class);
    list.forEach(System.out::println);
}

image-20230126201320551

Modify the age based on id.

image-20230126201446715

/**
 * 注入模板对象
 */
@Resource
private MongoTemplate mongoTemplate;


/**
 * 修改:
 * 根据id,修改年龄
 */
@Test
public void testUpdate() {
    
    
    //1、条件
    Query query = Query.query(Criteria.where("id").is("63d26be79e8d6402ffda6b21"));
    //2、修改后的数据
    Update update = new Update();
    update.set("age", 99);
    mongoTemplate.updateFirst(query, update, Person.class);
}

image-20230126201607838

Delete: Delete based on id.

/**
 * 注入模板对象
 */
@Resource
private MongoTemplate mongoTemplate;


@Test
public void testRemove() {
    
    
    Query query = Query.query(Criteria.where("id").is("63d26be79e8d6402ffda6b21"));
    mongoTemplate.remove(query, Person.class);
}

image-20230126201744462

Guess you like

Origin blog.csdn.net/weixin_53041251/article/details/128767428