MongoDB( 五 )MongoDB普通查询和聚合查询

本文介绍了MongoDB的普通查询、删除、更新和查询操作,以及聚合操作的聚合查询、排序、分组和关联查询示例。通过MongoTemplate演示了如何使用Spring Data进行CRUD和聚合操作,适合初学者了解MongoDB实践技巧。
摘要由CSDN通过智能技术生成

目录

 

一 : 普通操作

实例:

插入文档

 删除文档

 更新文档

 查询操作

二 : 聚合操作

aggregate() 方法

语法

 聚合基础查询

聚合查询、排序、分组、分页、Concat拼接

聚合查询链表关联查询

 


一 : 普通操作

MongoDB的普通查询MongoTemplate与Mysql的JdbcTemplate或者说是Redis的RedisTemplate别无二致 , 使用方式完全相同;

在使用之间创建一个临时使用的test集合, 结构如下

db.getCollection("testDocuments").insert( {
    _id: ObjectId("5fe9439e66730000e70058d0"),
    name: "huang",
    age: 21,
    gender: "男"
} );
db.getCollection("testDocuments").insert( {
    _id: ObjectId("5fe943bb66730000e70058d1"),
    name: "lu",
    age: 26,
    gender: "男"
} );
db.getCollection("testDocuments").insert( {
    _id: ObjectId("5fe943cf66730000e70058d2"),
    name: "huang",
    age: 2,
    gender: "女"
} );

实例:

  • 插入文档

1 . 使用mongoTemplate直接插入自定义实体类

        MongoTestDTO mongoTestDTO = new MongoTestDTO();
        mongoTestDTO.setName("huangxiapkuan");
        mongoTestDTO.setAge("21");
        mongoTestDTO.setGender("男");
        mongoTemplate.insert(mongoTestDTO , "testDocuments");

 2 . 使用mongoTemplate插入Mongo自带可动态扩展实体类Document.class

import org.bson.Document

// 批量插入 改为 insertMany(List<Document>) 即可
mongoTemplate.insert(new Document("name" , "zhang")
                .append("age" , "33").append("gender" , "男"), "testDocuments");

3 . MongoTemplate提供了官方客户端驱动的封装,官方客户端有的方法,它都能调用  , 此外还提供了一种更统一的execute方法,

             它通过注册一个回调,来实现MongoDB操作以及数据回传:

mongoTemplate.execute(mongodb -> {
            mongodb.getCollection("testDocuments").insertOne(new Document("name" , "isnert3")
                    .append("age" , "33").append("gender" , "男"));
            return "sucess";
        });

 4 . Mongo原生SQL如下: 

db.testDocuments.insert({
    name: 'huang',
    age: 2,
    gender: '男'
})

 

  •  删除文档

1 .  使用mongoTemplate进行删除操作 , 需要提供Query也就是条件   , 和集合名 , 注意以下使用的 remove()更换为 findAllAndRemove() 则为批量删除

     删除条件 name = ''insert3'' 的 数据

Query query =  new Query();
// Criteria 可自定义创建条件 
query.addCriteria(Criteria.where("name").is("insert3"));
mongoTemplate.remove(query , "testDocuments");

 删除条件 _id = ''5feae0eb47801f7dfef1bf2d'' 的 数据

Query query =  new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feae0eb47801f7dfef1bf2d")));
mongoTemplate.remove(query , "testDocuments");

2 . 使用 MongoTemplate.execute 来执行回调函数  ,用来进行删除操作 , 官方客户端有的方法,它都能调用

        mongoTemplate.execute( mongodb -> {
            mongodb.getCollection("testDocuments").deleteOne(new Document("name","isnert3"));
            return "sucess";
        });
        // 又或者
        mongoTemplate.execute("testDocuments" ,mongodb -> {
            mongodb.deleteOne(new Document("name","isnert3"));
            return "sucess";
        });

 3 . MongoDb原生SQL删除语句如下

db.testDocuments.remove({
    'name': 'insert3'
})
  •  更新文档

1 . 使用MongoTemplate.upsert(Query  , Update , CollectionName) 进行更新操作 

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;       
        
Query query =  new Query();
        query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
        Update update = new Update();
        update.set("name" , "new_set_values");
        UpdateResult result = mongoTemplate.upsert(query, update, "testDocuments");
        long count = result.getModifiedCount();
        if (count > 0) {
            return ApiResult.success("win!~");
        }

 2 . 使用MongoTemplate.execute() 回调函数进行更新操作

            // 注意这里 使用的 不是 Update 而是 Updates
            String execute = mongoTemplate.execute("testDocuments", mongodb -> {
            UpdateResult result = mongodb.updateMany(new Document("name", "isnert3"), Updates.set("name", "upr_execute_name"));
            long count = result.getModifiedCount();
            if (count > 0) {
                return "success";
            }
            return "error";
        });

 3 . 使用MongoDb原生SQl 进行更新操作

    db.getCollection('testDocuments').updateOne({
        name: 'new_set_values'
    }, {
        $set: {
            name: 'Mongo_set_name_new'
        }
    })
  •  查询操作

由于是测试用

1 . 使用MongoTemplate进行查询操作

 普通查询

// 查询所有
List<Document> testDocuments = mongoTemplate.find(new Query(), Document.class, "testDocuments");

// 条件查询 , 根据_id查询指定值
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
mongoTemplate.find(query, Document.class, "testDocuments");
// 也可以直接使用MongoTemplate提供的 findById()
mongoTemplate.findById("5feafa9b47801f7dfef1bf2e",Document.class , "testDocuments");

// 条件查询,查询特定name值
Query query = new Query();
query.addCriteria(Criteria.where("name").is("huang"));
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");

// 条件查询,查询特定name值 ,或者age年龄大于30的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(30));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");

// 条件查询,查询特定name值,并且年龄大于20的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(20));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");

//条件查询 , 分页查询 skip(0)  从第0条开始 , limit(2) 查询两条
Query query = new Query();
query.skip(0);
query.limit(2);
mongoTemplate.find(query, Document.class, "testDocuments");

//条件查询 , 排序 sort 可同时针对多个字段进行排序, 不过当数据量过大时可能会出现内存不足
// 具体解决办法可参照  https://blog.csdn.net/qq_42543063/article/details/111380373
Query query = new Query();
// query.with(Sort.by("age").descending()); // 倒序
query.with(Sort.by("age").ascending()); // 正序
mongoTemplate.find(query, Document.class, "testDocuments");

Mongo查询Query常用条件

 

Query.All("name", "a", "b");//通过多个元素来匹配数组
Query.And(Query.EQ("name", "a"), Query.EQ("title", "t"));//同时满足多个条件
Query.EQ("name", "a");//等于
Query.Exists("type", true);//判断键值是否存在
Query.GT("value", 2);//大于>
Query.GTE("value", 3);//大于等于>=
Query.In("name", "a", "b");//包括指定的所有值,可以指定不同类型的条件和值
Query.LT("value", 9);//小于<
Query.LTE("value", 8);//小于等于<=
Query.Mod("value", 3, 1);//将查询值除以第一个给定值,若余数等于第二个给定值则返回该结果
Query.NE("name", "c");//不等于
Query.Nor(Array);//不包括数组中的值
Query.Not("name");//元素条件语句
Query.NotIn("name", "a", 2);//返回与数组中所有条件都不匹配的文档
Query.Or(Query.EQ("name", "a"), Query.EQ("title", "t"));//满足其中一个条件
Query.Size("name", 2);//给定键的长度
Query.Type("_id", BsonType.ObjectId);//给定键的类型
Query.Where(BsonJavaScript);//执行JavaScript
Query.Matches("Title", str);//模糊查询 相当于sql中like  -- str可包含正则表达式

二 : 聚合操作

MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。

有点类似 SQL 语句中的 count(*)。


aggregate() 方法

MongoDB中聚合的方法使用aggregate()。

语法

aggregate() 方法的基本语法格式如下所示:

>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

 聚合基础查询

一下是本次测是使用的数据

 

  • 聚合查询、排序、分组、分页、Concat拼接

Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.group("name")
                        .max("age").as("maxAge")
        );
AggregationResults<Document> testDocuments = 
                mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);

等同于Mongo原生SQL如下:

查询结果 , 可以发现 , name被当做了_id , 且只查询出来了两个属性

{"_id":"upr_execute_name","maxAge":33},{"_id":"huang","maxAge":21},{"_id":"lu","maxAge":26}

 

可以将上面的聚合操作修改为如下

// 除却max 函数外 聚合操作还提供了  avg  min  sum 等常用计算函数
Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("gender").is("男")), // 查询条件
                Aggregation.project("name", "age", "gender")
                        .andExpression("concat('$gender', '人')").as("genderNew")
                ,// 可利用 andExpression() 继续操作某些特定值  加减乘如 或者拼接字符串
                Aggregation.group("name")
                        .max("age").as("maxAge") // 取最大年龄 , 别名为 maxAge
                .first("name").as("name") // 分组后取该组内第一条name
                .first("age").as("age")   
                .first("gender").as("gender"),
                Aggregation.skip(0L), // 始于第几条 mongo建议使用long类型
                Aggregation.limit(2L), // 查询多少条 
                Aggregation.sort(Sort.Direction.DESC,
                "age" , "name") // 可同时使用多字段排序 , 需注意当数据量过大时容易造成内存不足 具体解决办法 请参照 https://blog.csdn.net/qq_42543063/article/details/111380373
        );
AggregationResults<Document> testDocuments =
                mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);

查询结果样例为:

{"_id":"huang","maxAge":21,"name":"huang","age":21,"gender":"男"},{"_id":"lu","maxAge":26,"name":"lu","age":26,"gender":"男"}
  • 聚合查询链表关联查询

为了验证关联查询操作 , 此处需新建一个mongo的集合 , 旨在测试用 , 具体业务不严谨!!!



主表为  testDocuments  关联表为  testRel 

        // 创建条件集合
        List<AggregationOperation> aggregationOptions = new ArrayList<>();
        LookupOperation lookupOperation = LookupOperation.newLookup()
                .from("testRel") // 指定关联表
                .localField("name") // 关联表字段
                .foreignField("name") // 关联表字段
                .as("rel"); // 关联表别名
        aggregationOptions.add(lookupOperation); // 作为条件添加至条件集合
        // 为关联表创建条件
        aggregationOptions.add(Aggregation.match(Criteria.where("rel").elemMatch(Criteria.where("name").ne("").ne(null))));
        aggregationOptions.add(Aggregation.group("name")
                .max("age").as("maxAge")
                .first("name").as("name")
                .first("age").as("age")
                .first("gender").as("gender")
                .first("rel.address").as("assress"));
        // 将条件集合创建成聚合操作Aggregation
        Aggregation aggregation = Aggregation.newAggregation(aggregationOptions);
        AggregationResults<Document> testDocuments =
                mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值