First Entry-Getting Started with MongoDB

MongoDB


Introduction

What is MongoDB?

  • A document non-relational database with JSON as the data model

Why is it called a document database?

  • The document comes from "JSON Document", which is not a PFD or WORD document that we understand

MongoDB application scenarios

  • Game scenes , logistics, social networking, live video, log processing: massive data storage, unimportant data, certain query performance


installation

https://www.mongodb.com/download-center/community

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


Comparison between MongoDB and Mysql

Both are database concepts, MongoDB has no concept of primary and foreign keys

MongoDBmysql
settable
DocumentationA record (line)
Key in the documentTable field
Value in the documentField value


instruction

Connect to the server: mongo ip:port e.g. mongo localhost:27017

Display the currently used database: db

Switch database: use 数据库

Create a database: There is no command to create a database, you can use use to select a database, if it does not exist, it will automatically create it for us, but only if you add a document to the library will it be saved as a file

Display a collection of a database:show collections 或者 show tables

Database and collection: There is no fixed structure in MongoDB, you can use db.collection name.command to operate, you need to display the creation can be useddb.createCollection("集合名称")

Delete documents:

remove : can be deleted according to conditions, only delete documents, the collection does not delete, db.collection name.remove (condition) delete all documents without conditions

drop : delete the collection and index together


operating


Add insert

db.集合名.insert( 文档 ): db.users.insert({id: 1, name: “xuan”, age: 22})

1.往集合中添加文档时,集合不存在会自动创建集合
2.操作成功时,集合会给文档生成一个 _id字段,也可以自己指定 "_id": ObjectId("60bb143c120c0000dd006fa2")  


Update

sql :update users ser xx=111 where xx=111

db.集合名.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
---------------------------------------------------

参数解析:
1.query : update的查询条件,类似mysql中的 where条件
2.update:update的对象和一些更新的操作符(如$,$inc...)等 ,类似 set
3.upsert : 可选如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
4.multi : 可选,默认是false:只更新找到第一条记录
          true:条件查出来多条记录全部更新
5.writeConcern :可选, 设置复制集合存储策略     

--------------------------------------------------------------
例子:
1.updateOne:
#把一个带有name=xuan,修改其age值为30
db.users.updateOne({name: "xuan"}, {$set: {age: 30}})

2.updateMany:
#修改所有name=xuan,修改其name=kent,age=23
db.users.updateMany({name:"xuan"},{$set:{name:"kent",age:23}})
#修改所有的文档,修改其name=yue,age=18
db.users.updateMany({}, {$set: {name: "yue", age: 18}})


Remove/delete

db.集合名.remove(
  <query>,
  {
        justOne: <boolean>,
        writeConcern: <document>
  }
)
----------------------------------------

参数解析:
1.query :(可选)删除的文档的条件。
2.justOne :(可选)如果设为true或1,只删除一个文档.默认为false,删除所有匹配的条件

-----------------------------------------
简化方法:
1.删除1个:db.users.deleteOne({_id: ObjectId("xxx")})
2.删除所有:db.users.deleteMany({})


Inquire

find

sql :select age, name from table where …

db.集合名.find(query, projection)

参数解析:
1.query:条件
2.projection: 列的投影,指定返回哪些列 _id默认返回 eg: {"_id": 0}

-----------------------------------------------
#查所有用户
db.users.find()
#查看id,name 列  1表示显示,0表示不显示
//列挑选要注意,明确写出来的列(_id除外),要么都是0,要么都是1
db.users.find({},{id:1,name:1,_id:0})

Sort

sort({列:1}) //正序
sort({列:-1}) //倒序

#查询所有用户按年龄排序
db.users.sort({age:1})  //asc
db.users.sort({age:-1})  //desc

##查询所有用户按年龄排序,年龄一样.使用id排序
db.users.sort({age:1,id:-1})  

Paging mimit

**sql: select * from users limit 0, 3 **

db.集合.find({}).skip(n).limit(m)
db.users.find().skip((currentPage-1) * pageSize).limit(pageSize)

第一页
db.users.find({}).skip(0).limit(3)
第二页
db.users.find({}).skip((2-1)*3).limit(3)
第三页
db.users.find({}).skip((3-1)*3).limit(3)


Comparison operator

  • **Greater than: $gt **
  • <Less than: $lt
  • = Greater than or equal to: $gte
  • <= Less than or equal to: $lte
  • != Not waiting: $ne
#查询age >30的用户
db.users.find( {   age:{$gt:30}  } )
#查询名字为xuan或者yue 用户
  db.users.find( 
  {   name:{$in: ["xuan","yue"]}  } 
)


Determine whether the specified column exists

#查询拥有name列的属性
db.users.find( 
  {   name:{$exists:false }  } 
)


Logical Operators

  • && 与 : $and
  • || 或 : $or
  • ! Not: $not
SQLMQL
a=1 AND b=2{$and: [{a:1}, {b:2}]} or {a:1 ,b:2}
a=1 ORb=2{ $or: [ {a:1}, {b:2} ] }
a is null{a : {$exists:false } }
a in (1,2,3){a : {$in:[1,2,3] } }
find({逻辑操作符:[条件1,条件2,....]})
--------------------------------------

#查询年龄在25到30间的用户信息
  db.users.find( 
  {   $and:[{age:{$gte:25}},{age:{$lte:30}]  } 
)
简写:
db.users.find( 
  {   age:{$gte:25,$lte:30}  } 
)


Fuzzy query

sql :select * from user where name like '%关键字%'

  • {name:/xxx/} —>%xxx%
  • {name:/^xxx/} —>xxx%
  • {name:/xxx$/} —>%xxx
  • {name:/xxx/i} ignore case
db.集合.find(   {   列: {$regex: /关键字/}  }   )   #正则对象(js)
db.集合.find({列: {$regex: "关键字"}})

#查询name带有ent的用户信息
db.users.find(
  {name: {$regex:/ent/ }}
)
#查name中包含k字样,并且年龄在20 到 25间的用户信息
db.users.find(
   {$and: [{name: {$regex:/k/}}, {age: {$gte:20, $lte:25}}]}
)


Document design

  • Normal document
  • Document nesting
  • Array mode

To be added…


Points to note when integrating Springboot

mongoDB接口定义:
1.自定义接口,继承MongoRepository
2.添加2个泛型:
泛型1:操作实体对象User
泛型2:实体主键id类型String 
  
问题点1:
UserRepository 没有定义curd方法为啥可以在service层调用crud方法操作?
  因为UserRepository继承了MongoRepository接口,而有了crud方法
  
问题点2:
没有包扫描,为什么UserRepository接口就有实现类ne?
  spring-boot-data-MongoDB 这个框架在项目启动的时候会自动扫描所有UserRepository接口的子接口,自动动态代理创建对象,交给容器管理
  
问题3:
  直接在接口中定义findByName方法,就可以直接调用了,而不需要进行实现,怎么做到?
   上面操作跟 JPA查询方法定义 规范有关 
    spring-boot-data-MongoDB 这个框架实现了JPA规范

rely:

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/>
    </parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>    
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
  
<!--spring boot data mongodb-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
</dependencies>

Code:

1.实体类User
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@ToString
@Document("users") //设置文档所在的集合
public class User {
    //文档的id使用ObjectId类型来封装,并且贴上@Id注解,
    // 自动映射为_id 自动封装ObjectId
    @Id
    private String id;
    private String name;
    private Integer age;
    private List<String> hobby = new ArrayList<>();
}
----------------------------------------
  2.接口repository
  public interface UserMongoRepository extends MongoRepository<User,String> {
}
-----------------------------------------
  3.实现类接口 与实现类
  public interface IUserService {
    void save(User user);

    void delete(String id);

    void update(User user);

    User get(String id);

    List<User> list();
}
--------
 @Service
public class UserServiceImpl  implements IUserService {

    @Autowired
    private UserMongoRepository userRepository;

    @Override
    public void save(User user) {
        userRepository.save(user);
    }
    @Override
    public void delete(String id) {
        userRepository.deleteById(id);
    }
    @Override
    public void update(User user) {
        userRepository.save(user);
    }
    @Override
    public User get(String id) {
        return userRepository.findById(id).get();
    }
    @Override
    public List<User> list() {
        return userRepository.findAll();
    }
}


JPA

JPA query method specification convention: prefix + operator + attribute

  • Prefix: find /query
  • Operator: by and or…
  • Attribute: table column/domain attribute

Limitations: The JPA query specification has certain restrictions. The query conditions cannot be too many. It can only be used for simple and small query advanced queries. Multi-condition queries will not work. You can use mongoTemplate to splice MQL query statements.

Insert picture description here