栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot集成mongoDB高级聚合查询,关联查询.

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot集成mongoDB高级聚合查询,关联查询.

目录

mongoDB的常用操作符

mongoDB的聚合管道符号

比较操作符

逻辑运算符 

数学运算符

mongoDB案例

        插入测试数据

 mongodb的阶段操作符号

                关联查询

springBoot整合mongoDB

        pom依赖

         yml配置

java代码案例


mongoDB的常用操作符

mongoDB的聚合管道符号
db.collection.aggregate( [ { }, ... ] )使用aggregate()方法来构建和使用聚合管道。

比较操作符

$eq        “=” 等于 $gt         “>” 大于$gte        ”>=“ 大于等于$lt            “<” 小于$lte          ”<= “小于等于$ne          ”!=" 不等于$in           相当于MySQL的in$nin         相当于MySQL的nin

案例:db..find({ : { $gt: } })     

逻辑运算符 

$or        OR或相当于MySQL的OR

案例:

db..find({$or:[{:{$lt:}},{:}], :})

 limit      跳过指定数量的文档

skip       查询指定数量的文档

案例:

db..find({}).skip(20).limlit(20)

数学运算符

$add        加法     $subtract        减法$multiply        乘法$divide        除法$mod        求余

mongoDB案例

        插入测试数据

db.student22.insertMany([{
  "name": "张0",
  "gender": "女",
  "age": 0,
  "math": NumberInt(84),
  "language":NumberInt(99),
  "classes": "一年级二班",
  "Hobby": [ "蓝色", "蓝色1", "蓝色2" ]
},{
  "name": "张1",
  "gender": "男",
  "age": 1,
  "math": NumberInt(42),
  "language": NumberInt(48),
  "classes": "一年级二班",
  "Hobby": [ "绿色", "绿色1", "绿色2" ]
},{
  "name": "张2",
  "gender": "女",
  "age": 2,
  "math": NumberInt(71),
  "language": NumberInt(33),
  "classes": "一年级一班",
  "Hobby": ["青色", "青色1", "青色2" ]
},{
  "name": "张3",
  "gender": "男",
  "age": 3,
  "math": NumberInt(93),
  "language": NumberInt(2),
  "classes": "一年级一班",
  "Hobby": [ "黄色", "黄色1","黄色2"]

}])

 mongodb的阶段操作符号

所用的案例都是用的上面插入的数据

$match:

        格式:  {$match:}

        介绍:  指定某个字段的查询条件,相当于MySQL中的 where

        案例: 

              筛选math大于30,language小于100的信息

//可以结合上面的比较运算符,数学运算符,逻辑运算符操作
db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}}
])      

-------------------------------------------------------------------------------------------------------------------------

$count

        格式: {$count : }

        介绍:  返回总条数;  等价于MySQL中的count函数

        案例: 

              筛选math大于30,language小于100的总记录数

db.student22.aggregate([
      {$match:{classes:"一年级一班",math:{$gt:60},language:{$lt:80}}},
      {$count:"name"}
])   

-------------------------------------------------------------------------------------------------------------------------

$group

        格式: 

                {$group:{_id:, : { : }} }

        介绍:

                使用该阶段符分组查询  

                该运算符必须是以下累加器运算符之一 (案例中有介绍)

                字段名称前加一个美元符号$并用引号引起来

        案例:

                 筛选math大于30,language小于100的记录, 根据classes字段分组查询,求出每个分组math字段的和.

db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}}, //$sum:1 则会返回每个分组的总记录数
      {$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
      
])

-------------------------------------------------------------------------------------------------------------------------

$project

        格式:  {$project:}

        介绍:  指定哪些字段进入下阶段管道,或者返回。0:false ,1:true

        案例:

                接着上面的分组案例往下来,我们排除name和gender字段不接收

db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}},
      {$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
      {$project:{name:0,gender:0}}  //字段:0 表示排除他
])   

-------------------------------------------------------------------------------------------------------------------------

$addFields

        格式:  {$addFields::}

        介绍: 

                  将新字段添加到文档。$addFields输出包含输入文档中所有现有字段

                  和新添加的字段的文档 . 字段名称前加一个美元符号$并用引号引起来

        案例:

                新加一个nowField字段.并且为每组的总分(mathCount字段)加1

db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}},
      {$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
      {$project:{name:0,gender:0}},
      //每个条记录都会增加nowField这个文档, 每条记录的mathCount都会加1
      {$addFields:{nowField:"我是新加的字段",mathCount:{$add:["$mathCount",1]}}}
])   

-------------------------------------------------------------------------------------------------------------------------


$set

        格式:  {$set::}

        介绍: 

                将新字段添加到文档。$set输出包含输入文档中所有现有字段和新添加的字段的文档。

                $set 和 $addFields这两个阶段等效于一个$project阶段.

                字段名称前加一个美元符号$并用引号引起来

-------------------------------------------------------------------------------------------------------------------------

$redact

        格式:  { $redact: }      

        介绍:  

                根据条件限制文档的内容。

        案例:

                跟着上面的案例继续聚合, 使用$redact符筛选出mathCount字段大于160的数据  

db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}},
      {$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
      {$project:{name:0,gender:0}},
      {$addFields:{nowField:"我是新建的字段",mathCount:{$add:["$mathCount",1]}}},
      {$redact:{
           $cond:{
                if:{
                     $gt:["$mathCount",160]},
                then:"$$KEEP",
                else:"$$PRUNE"
      }}}
])

 

-------------------------------------------------------------------------------------------------------------------------

$lookup

        格式:   

{
   $lookup:
     {
       from: ,
       localField: ,
       foreignField: ,
       as: 
     }
}

        介绍: 

                关联查询

                使用该操作符实现表之间的关联查询

        案例:

//插入parent22表,与上面的student22表关联, 
//关联的字段是name,关联的字段名可以不同,但是值必须相同,丛主表关联的字段类型必须相同(除数组类型外)
db.parent22.insertMany([
     {name:"张0",mobile:1304444444,parentName:"张0的爸爸"},
     {name:"张1",mobile:1374444444,parentName:"张1的爸爸"},
     {name:"张0",mobile:1594444444,parentName:"张0的妈妈"},
     {name:"张1",mobile:1864444444,parentName:"张1的妈妈"},
])


//mongo查询案例
db.student22.aggregate([
     {$lookup:{
          from:"parent22", //关联从表的表名
          localField:"name", //主表关联的字段 
          foreignField: "name", //从表关联的字段(从表类型也可以是数组).
          as:"pr" //给结果起个别名
     }
   }
])
//java实现的案例
    @Autowired
    private MongoTemplate mongoTemplate;
    @Test
    public void mongoTest(){
     Aggregation aggregation = Aggregation.newAggregation(Aggregation.lookup("从表表名", "主表关联字段名", "从表关联字段", "结果起的别名"));

        AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
        //获取结果
        List mappedResults = result.getMappedResults();
}

//mongo查询返回的结果
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"), 
    "name" : "张0", 
    "gender" : "女", 
    "age" : 4.0, 
    "math" : NumberInt(84), 
    "language" : NumberInt(99), 
    "classes" : "一年级二班", 
    "Hobby" : ["蓝色", "蓝色1", "蓝色2"], 
    "pr" : [
        {
            "_id" : ObjectId("623151398a0c4bd7d10ac962"), 
            "name" : "张0", 
            "mobile" : 1304444444.0, 
            "parentName" : "张0的爸爸"
        }, 
        {
            "_id" : ObjectId("623151918a0c4bd7d10ac966"), 
            "name" : "张0", 
            "mobile" : 1304444444.0, 
            "parentName" : "张0的爸爸"
        }, 
        {
            "_id" : ObjectId("623151918a0c4bd7d10ac968"), 
            "name" : "张0", 
            "mobile" : 1594444444.0, 
            "parentName" : "张0的妈妈"
        }
    ]
}
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac95f"), 
    "name" : "张1", 
    "gender" : "男", 
    "age" : 1.0, 
    "math" : NumberInt(42), 
    "language" : NumberInt(48), 
    "classes" : "一年级二班", 
    "Hobby" : [
        "绿色", 
        "绿色1", 
        "绿色2"
    ], 
    "pr" : [
        {
            "_id" : ObjectId("623151398a0c4bd7d10ac963"), 
            "name" : "张1", 
            "mobile" : 1374444444.0, 
            "parentName" : "张1的爸爸"
        }, 
        {
            "_id" : ObjectId("623151918a0c4bd7d10ac967"), 
            "name" : "张1", 
            "mobile" : 1374444444.0, 
            "parentName" : "张1的爸爸"
        }, 
        {
            "_id" : ObjectId("623151918a0c4bd7d10ac969"), 
            "name" : "张1", 
            "mobile" : 1864444444.0, 
            "parentName" : "张1的妈妈"
        }
    ]
}
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac960"), 
    "name" : "张2", 
    "gender" : "女", 
    "age" : 2.0, 
    "math" : NumberInt(71), 
    "language" : NumberInt(33), 
    "classes" : "一年级一班", 
    "Hobby" : [
        "青色", 
        "青色1", 
        "青色2"
    ], 
    "pr" : [
        {
            "_id" : ObjectId("623151398a0c4bd7d10ac964"), 
            "name" : "张2", 
            "mobile" : 1594444444.0, 
            "parentName" : "张2的爸爸"
        }
    ]
}
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac961"), 
    "name" : "张3", 
    "gender" : "男", 
    "age" : 3.0, 
    "math" : NumberInt(93), 
    "language" : NumberInt(2), 
    "classes" : "一年级一班", 
    "Hobby" : [
        "黄色", 
        "黄色1", 
        "黄色2"
    ], 
    "pr" : [
        {
            "_id" : ObjectId("623151398a0c4bd7d10ac965"), 
            "name" : "张3", 
            "mobile" : 1864444444.0, 
            "parentName" : "张3的爸爸"
        }
    ]
}

-------------------------------------------------------------------------------------------------------------------------

$unwind

        格式:  {$unwind :}

        介绍:            

                拆分数组,数组中的每个数据都会生成一条记录.

                字段名称前加一个美元符号$并用引号引起来 

         案例:

                查询name等于"张0"的记录,该记录中有个Hobby字段是数组类型,将该数组拆分

db.student22.aggregate([
     {$match:{name:"张0"}},
     {$unwind:"$Hobby"}  

])

-------------------------------------------------------------------------------------------------------------------------

$geoNear

        格式:  {$geoNear:}

        介绍: 

                指定经纬度点,从mongodb中查询,最近到最远的顺序输出文档。

        案例:参考这里

-------------------------------------------------------------------------------------------------------------------------

$bucket

        格式: 

        {
          $bucket: {
              groupBy: ,
              boundaries: [ , , ... ],
              default: ,
              output: {
                 : { <$accumulator expression> },
                 : { <$accumulator expression> }
              }
           }
        }

        介绍: 

                根据自定义条件分组

        案例:   

                根据年龄区间分组

db.student22.aggregate([
     {$bucket:{
          groupBy: "$age",  //根据age字段分组
          boundaries:[1,4], //年龄再1到4之间(左开右闭.包含1,不包含4)的分一个组
          default: "Other",   //没有达到条件的分一个组
          output:{
              "student22":{
                   $push:{
                        "age":"$age"   //这里表示将分组后的所有年龄数组
                   }
              }
          }  
     }}
])

//对应的Java代码 -------------------------------------------------------------------------->
import org.springframework.data.mongodb.core.MongoTemplate;

@Autowired
private MongoTemplate mongoTemplate;  

@Test
public void mongoTest(){
    
     Aggregation newAggregation = Aggregation.newAggregation(
                Aggregation.bucket("age")
                        .withDefaultBucket("other")
                        .withBoundaries(1, 4)
                        .andOutput("age")
                        .push().as("student22")
        );
   
    AggregationResults result = mongoTemplate
                                       .aggregate(newAggregation, "你的表名", 实体类.class);
        //获取结果
        List mappedResults = result.getMappedResults();
}

springBoot整合mongoDB

        pom依赖

    org.springframework.boot
    spring-boot-starter-data-mongodb

         yml配置
spring:
  data:
    mongodb:
      uri: mongodb://用户名:密码@IP:端口/数据库名字?authSource=admin&authMechanism=SCRAM-SHA-1

java代码案例
    @Autowired
    private MongoTemplate mongoTemplate;
    public void mongoTest(){

        ConditionalOperators.Cond condition = ConditionalOperators.Cond.when((Criteria.where("表中的字段名1").is("等于的值"))).thenValueOf("").otherwisevalueOf("");

        //在这里构造我们的聚合条件
        Aggregation aggregation = Aggregation.newAggregation(
                //根据自己的业务构造自己的条件
                Aggregation.match(Criteria.where("表中的字段名1").is("等于的值").and("表中的字段名2").in("等于的值")),
                Aggregation.group("要分组的字段名").first("表中的字段名").as("起的别名"),
                Aggregation.project().andExclude("排除的字段").andInclude("包含的字段"),
                Aggregation.addFields().addField("nowField").withValue("新建的字段").build().and().addField().withValueOfexpression("a", 1, 2).build(),
                Aggregation.unwind("表中数组字段名"),
                Aggregation.redact(condition)
        );
        //查询
        AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
        //获取结果
        List mappedResults = result.getMappedResults();
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/770569.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号