MongoDb使用

一、数据库、集合增删(命令行方式)

1.1 连接mongo

mongo --port 7023  # 连接mongo
db.auth('user', 'pwd')  # 验证身份

1.2 用户管理

# 创建用户
use admin  # 切换至admin数据库
db.createUser({user: "root", pwd: "12345", roles: ["readWriteAnyDatabase", "userAdminAnyDatabase", "dbAdminAnyDatabase"])  # 创建root用户

# 为数据库aa创建具有读写权限的用户
use aa
db.createUser({user: "mongou",pwd: "123",roles: ["dbOwner"]}) 

# 修改用户权限
db.updateUser("mongou", {pwd: "123",roles: [ { role: "readWrite", db: "b" } ]})

# 追加用户权限
db.grantRolesToUser("mongou", [{role:"readWrite", db:"test"}])  

# 删除用户
db.dropUser("mongou")

1.2 数据库管理

# 切换到aa数据库,若不存在则创建
use aa

# 刚创建的数据库 runoob 并不在数据库的列表中, 要显示它,我们需要向 runoob 数据库插入一些数据。
db.aa.insert({"name":"sky"})

# 删除数据库
db.dropDatabase()

1.3 集合管理

# 创建集合
db.createCollection("user")

# 删除集合
db.user.drop()

1.4 文档管理

# 插入文档
db.col.insert({"name":"sky"})
db.col.insertMany([{"name":"sky"}, {"name":"jack"}])

二、SpringBoot集成Spring Data Mongodb

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

application.yml

spring:
  data:
    mongodb:
      host: 127.0.0.1
      port: 7000
      database: user
      username: mongou
      password: pass

三、MongoTemplate增删改查

注入MongoTemplate

@Resource
private MongoTemplate mongoTemplate;

2.1 插入

// 插入一个对象
mongoTemplate.insert(obj, 'col_name'); 

// 插入多个对象
mongoTemplate.insert(objList, 'col_name');

2.2 删除

Criteria criteria = Criteria.where("age").is(12).and("sex").is('男');
Query query = new Query(criteria);
DeleteResult result = mongoTemplate.remove(query, 'col_name');

2.3 修改

mongoTemplate.save(obj, COLLECTION_NAME);

2.4 查询

// 查询集合中的【全部】文档
List<User> documentList = mongoTemplate.findAll(User.class, COLLECTION_NAME);

// 根据【文档ID】查询
User user = mongoTemplate.findById(id, User.class, COLLECTION_NAME);

// 条件查询,只取【第一条】数据
Criteria criteria = Criteria.where("age").is(age);
Query query = new Query(criteria);
User user = mongoTemplate.findOne(query, User.class, COLLECTION_NAME);

// 条件查询,获取其【文档列表】
Criteria criteria = Criteria.where("sex").is(sex);
Query query = new Query(criteria);
List<User> documentList = mongoTemplate.find(query, User.class, COLLECTION_NAME);

// 条件查询,获取其【文档列表】并【排序】
Criteria criteria = Criteria.where("sex").is("男");
Query query = new Query(criteria).with(Sort.by("age"));
List<User> documentList = mongoTemplate.find(query, User.class, COLLECTION_NAME);

// 条件查询,排序并limit
Criteria criteria = Criteria.where("sex").is("男");
Query query = new Query(criteria).with(Sort.by("age")).limit(5);
List<User> documentList = mongoTemplate.find(query, User.class, COLLECTION_NAME);

// 条件查询,分页
Criteria criteria = Criteria.where("sex").is("男");
Pageable pageable = PageRequest.of(0, 10, Sort.by("age"));
Query query = new Query(criteria).with(pageable);
List<User> documentList = mongoTemplate.find(query, User.class, COLLECTION_NAME);

// 统计数目,count()
Criteria criteria = Criteria.where("age").is(12);
Query query = new Query(criteria);
long count = mongoTemplate.count(query, User.class, COLLECTION_NAME);
// 多条件查询
Query query = new Query();
if (cid != null)
    query.addCriteria(Criteria.where("cid").is(cid));
if (name != null)
    query.addCriteria(Criteria.where("name").regex(name));
List<Course> courses = mongoTemplate.find(query, Course.class, COURSE_COLLECTION);

2.5 聚合group

AggregationOperation group = Aggregation.group("age").count().as("numCount");
Aggregation aggregation = Aggregation.newAggregation(group);
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);

其他函数

count()、max()、min()、sum()、avg()、first()、last()

2.6 聚合管道

// condition + group
AggregationOperation match = Aggregation.match(Criteria.where("age").lt(25));
AggregationOperation group = Aggregation.group("sex").max("salary").as("sexSalary");
Aggregation aggregation = Aggregation.newAggregation(match, group);
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);

// group + sort
AggregationOperation group = Aggregation.group("age")
        .max("salary").as("ageSalary")
        .count().as("ageCount");
AggregationOperation sort = Aggregation.sort(Sort.by("ageSalary").ascending());
Aggregation aggregation = Aggregation.newAggregation(group, sort);
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);

// group + limit
AggregationOperation group = Aggregation.group("age").avg("salary").as("avgSalary");
AggregationOperation limit = Aggregation.limit(5L);
Aggregation aggregation = Aggregation.newAggregation(group, limit);
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);

2.7 join $lookup外连接

// class集合,外键为student_id
{
    "_id": ObjectId("5f13a185167a9003cf76206b"),
    "class_num": 1,
    "student_id": 1
}
{
    "_id": ObjectId("5f13a18b167a9003cf76206c"),
    "class_num": 2,
    "student_id": 2
}
------------------------------------------------
// student集合,主键_id
{
    "_id": 1,
    "name": "lihui",
    "job": "IT",
    "age": 17
}
{
    "_id": 2,
    "name": "lilei",
    "job": "TEA",
    "age": 18
}
// 命令行查询
// from:class作为主collection,from字段表示需要链接的collection,不明白为啥命名个from
// localField:主collection里的外键字段
// foreignField:连接collection里对应外键的字段
// as:最终连接的部分输出的字段名称

db.class.aggregate([
    {
        $lookup:
            {
                from: "student",
                localField: "student_id",
                foreignField: "_id",
                as: "class_student_infos"
            }
    }
])

// 结果
{
    "_id": ObjectId("5f12bef9167a9003cf762068"),
    "class_id": 3,
    "student_id": 3,
    "class_student_infos": [
        {
            "_id": 3,
            "name": "MEIMEI",
            "job": "HR",
            "age": 16
        }
    ]
}
{
    "_id": ObjectId("5f12bf1d167a9003cf762069"),
    "class_id": 2,
    "student_id": 2,
    "class_student_infos": [
        {
            "_id": 2,
            "name": "lilei",
            "job": "TEA",
            "age": 18
        }
    ]
}
AggregationOperation match = Aggregation.match(Criteria.where("sid").is(sid));
LookupOperation lookupOperation = LookupOperation.newLookup().from("course").localField("cid").foreignField("_id").as("course");
Aggregation aggregation = Aggregation.newAggregation(match, lookupOperation);
AggregationResults<Map> student_course = mongoTemplate.aggregate(aggregation, "student_course", Map.class);

四、事务

3.1 配置事务管理器

/**
 * 配置事务管理器
 */
@Configuration
public class TransactionConfig {
    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }
}

3.2 事务使用

@Transactional(rollbackFor = Exception.class)
public Object transactionTest(){
    // 设置用户信息
    User user = new User()
            .setAge(22)
            .setSex("男")
            .setStatus(new Status().setHeight(180).setWeight(150));
    // 插入数据
    User newUser = mongoTemplate.insert(user1, COLLECTION_NAME);
    // 抛出异常,观察数据是否进行回滚
    int error = 1/0;
    return newUser;
}

hhhhh