目录

mongoDB的常用操作符

mongoDB的聚合管道符号

比较操作符

逻辑运算符 

注意坑 

数学运算符

mongoDB案例

插入测试数据

 mongodb的阶段操作符号

$match:

$count

$group

$replaceRoot

$project

$addFields

$sort

$set

$redact

$lookup

                关联查询

$unwind

$geoNear

$bucket

springBoot整合mongoDB

        pom依赖

         yml配置

java代码案例

Java操作MongoDB技巧:



mongoDB的常用操作符

mongoDB的聚合管道符号

db.collection.aggregate( [ { <stage> }, ... ] )

使用aggregate()方法来构建和使用聚合管道。

比较操作符

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

案例:db.<CollectionName>.find({ <field>: { $gt: <value> } })     

逻辑运算符 

  • $or        OR或相当于MySQL的OR

案例:

db.<CollectionName>.find({$or:[{<field>:{$lt:<value>}},{<field>:<value>}], <field>:<value>})

  •  limit      跳过指定数量的文档
  • skip       查询指定数量的文档

案例:

db.<CollectionName>.find({}).skip(20).limlit(20)

注意坑

1. 区间查询

$and逻辑符号,这样查询;

正确案例:

        db.<CollectionName>.find({$and[{age:{$gte:30}},{age:{$lte:60}}]})

或者:        

        db.<CollectionName>.find({age:{$gte:30,$lte:60}})

错误案例:(这种他不是区间查询,第二个条件会覆盖掉第一个条件)

        db.<CollectionName>.find({age:{$gte:30},age:{$lte:60}})


2. NumberLong类型


        Mongo的NumberLong长度超过19,查询要强转。

假如说我们age字段是NumberLong类型的。存入的数据超过19位,查询的需要强转一下,不然呢查询不到

正确案例

        db.heartBpmHistory.find({age:{$gte:NumberLong('30'),$lte:NumberLong('60')}})

错误案例一:

        db.<CollectionName>.find({age:{$gte:30,$lte:60}})

错误案例二

         db.heartBpmHistory.find({age:{$gte:NumberLong(30),$lte:NumberLong(60)}})

springboot如何判断mongodb集合一创建 spring data mongodb 聚合查询_数据库


数学运算符

  • $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"]}]) 
 下面的Java案例中关于mongodb操作的类皆来与
 
 
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.junit4.SpringRunner;
 
 
包中,请注意引包问题

 mongodb的阶段操作符号

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

$match:

field:value>}
        介绍:  指定某个字段的查询条件,相当于MySQL中的 where
        案例: 
              筛选math大于30,language小于100的信息
//可以结合上面的比较运算符,数学运算符,逻辑运算符操作
db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}}
])      
-------------------------------------------------------------------------------------------------------------------------
$count
field>}
        介绍:  返回总条数;  等价于MySQL中的count函数
        案例: 
              筛选math大于30,language小于100的总记录数
db.student22.aggregate([
      {$match:{classes:"一年级一班",math:{$gt:60},language:{$lt:80}}},
      {$count:"name"}
])   
-------------------------------------------------------------------------------------------------------------------------
$group
        格式: 
Field>, <field1>: { <accumulator1> : <expression1> }} }

        介绍:

                使用该阶段符分组查询  

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

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

        案例:

筛选math大于30,language小于100的记录, 根据classes字段分组查询,求出每个分组math字段的和.
//第一种方式,_id会被覆盖
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"}}},
      
])

//第二种id不会别覆盖的方式
db.student22.aggregate([
      {$match:{math:{$gt:30},language:{$lt:100}}}, //$sum:1 则会返回每个分组的总记录数
      {$group:{_id:"$classes",data:{$first:"$$ROOT"}}},
      {$replaceRoot: { newRoot: "$data" }},
      
])
/**  ---------------累加器运算符---------------------------------------------
$addToSet	    返回每个组的唯一表达式值的数组。数组元素的顺序未定义。
$avg	        返回数值的平均值。忽略非数字值。
$first	        从每个组的第一个文档返回一个值。仅当文档按定义的顺序定义顺序。
$last	        从每个组的最后一个文档返回一个值。仅当文档按定义的顺序定义顺序。
$max	        返回每个组的最高表达式值。
$mergeObjects	返回通过组合每个组的输入文档而创建的文档。
$min	        返回每个组的最低表达式值。
$push	        返回每个组的表达式值数组。
$stdDevPop	    返回输入值的总体标准偏差。
$stdDevSamp	    返回输入值的样本标准偏差。
$sum	        返回数值的总和。忽略非数字值。

**/

 //java代码实现

@Autowired
private MongoTemplate mongoTemplate;
 public void mongoGroupTest(){
        Aggregation aggregation = Aggregation.newAggregation(
                //先筛选
                Aggregation.match(Criteria.where("math").gt(30).and("language").lt(100)),
                //加入我们要娶每组中最大的一条记录,就可以先在这里倒叙,然后去第一天记录
                Aggregation.sort(Sort.Direction.DESC,"排序字段"),
                //在分组
                Aggregation.group("classes").first("$$ROOT").as("data"),
                //然后复原
                Aggregation.replaceRoot().withValueOf("data")
        );
        //查询
        AggregationResults<AttackSecurityEntity> aggregate = mongoTemplate.aggregate(aggregation, "你的表名", 实体类名.class);
        List<AttackSecurityEntity> results = aggregate.getMappedResults();//获取数据
    }

$replaceRoot

        介绍:  

                将嵌套的数据提取出来, 

replacementDocument>一定要是个对象字段,或者没有该字段都会报错

        格式:  { $replaceRoot: { newRoot: <replacementDocument> } }

        案例:

//插入测试数据
db.demo10.insert({
     name:"测试$replaceRoot符的数据",
     data:{
          id:NumberInt(123),
          name:"张上",
          age:NumberInt(12)
     }
})

//demo01中嵌套了一个对象叫data,假如说我们的需求就只需要data对象,
//那么我们可以使用$replaceRoot阶段符号实现

//Mongo语句实现
db.demo10.aggregate( [
   { $replaceRoot: { newRoot: "$data" } }
] )

//Java案例在group案例中有实现

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

$project

field:0,field:1>}

        介绍:  指定哪些字段进入下阶段管道,或者返回。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 表示排除他
])   

//Java案例在文章末尾“java案例”中有写

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

$addFields

格式:  {$addFields:<newField>:<value>}

        介绍

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

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

        案例:

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]}}}
])   
//Java案例在文章末尾“java案例”中有显示

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

$sort

         格式:   {$sort:{ <field1>: <sort order>, <field2>: <sort order> ... } }

         介绍:    排序符, -1 表示倒叙, 1表示正序

         案例:    

                为总分(mathCount字段) 倒叙排序.

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]}}},
      {$sort:{mathCount:-1}}
]) 

//Java案例在文章末尾“java案例”中有显示

$set

        格式:  {$set:<newField>:<value>}

        介绍

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

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

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

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

$redact

        格式:  { $redact: <expression> }      

        介绍:  

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

        案例:

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"
      }}}
])

/**then 和 else 可以是任何有效表达式,只要它解析为$$ DESCEND, $$ PRUNE或$$ KEEP系统变量即可。
    
$$ DESCEND :	$redact返回当前文档级别的字段,不包括嵌入式文档。要将嵌入式文档和嵌入式文档包含在数组中,请将$cond 表达式应用于嵌入式文档,以确定对这些嵌入式文档的访问。

$$ KEEP: 	$redact返回或将所有字段保留在当前文档/嵌入式文档级别,而无需进一步检查此级别的字段。即使所包含的字段包含可能具有不同访问级别的嵌入式文档,这也适用。
$$PRUNE:    $redact在当前文档/嵌入文档级别排除所有字段,而无需进一步检查任何排除的字段。即使排除字段包含具有不同访问级别的嵌入式文档,这也适用。

**/

//Java代码实现
 @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void mongoTest(){
        //构造$redact的条件
        ConditionalOperators.Cond cond = ConditionalOperators.Cond.when(ComparisonOperators.Gt.valueOf("mathCount").greaterThanValue(160)).then("$$KEEP").otherwise("$$PRUNE");
        Aggregation aggregation = Aggregation.newAggregation(
                //先筛选
                Aggregation.match(Criteria.where("math").gt(30).and("language").lt(100)),
                //在分组
                Aggregation.group("classes").sum("$math").as("mathCount").last("_id").as("id").last("name").as("name"),
                //追加字段
                Aggregation.addFields().addField("nowField").withValue("我是新建的字段").addFieldWithValue("mathCount", ArithmeticOperators.Add.valueOf("mathCount").add(1)).build(),
                //排除字段
                Aggregation.project().andExclude("name","gender"),
                Aggregation.redact(cond)
        );
        //查询
        AggregationResults<AttackSecurityEntity> aggregate = mongoTemplate.aggregate(aggregation, "你的表名", 实体类名.class);
        List<AttackSecurityEntity> results = aggregate.getMappedResults();
    }

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

$lookup

        格式:   

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

        介绍: 

                关联查询

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

        案例:

//插入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关联查询案例 1
db.student22.aggregate([
     {$lookup:{
          from:"parent22", //关联从表的表名
          localField:"name", //主表关联的字段 
          foreignField: "name", //从表关联的字段(从表类型也可以是数组).
          as:"pr" //给结果起个别名
     }
   }
])
/*相当于MySQL的
select t.*,p.* from student22 as t,parent22 as p where t.name = p.name */

//java实现的案例
    @Autowired
    private MongoTemplate mongoTemplate;
    @Test
    public void mongoTest(){
     Aggregation aggregation = 
                        Aggregation.newAggregation(
                                    Aggregation.lookup(
                                                    "从表表名", 
                                                    "主表关联字段名", 
                                                    "从表关联字段", 
                                                    "结果起的别名"));

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


--------------------------------------多条件关联查询案例--------------------------------

//mongo多条件关联查询案例 2
db.student22.aggregate([
     {$lookup:{
          from:"parent22", //关联从表的表名
          let: {
                    // 主表用来要作为筛选条件的字段 
                    Sname: "$name", 
                    pName:"$parentName"
                },
                pipeline: [{
                    $match: {
                        name:{$eq:"张1"} // 筛选从表name字段等于‘张1’的信息  
                    }
                },
                {
                    $match: {
                               $expr: {  //也可以使用expr,在expr中写聚合表达式
                            // 表示筛选从表name字段和主表parentName字段相等的
                               $eq: ["$name","$$pName"] 
                }
             }    
        }
            //下面还可以继续指定其他管道阶段符合
],
          as:"pr" //给结果起个别名
     }
   }
])

/*
  mongodb多条件关联查询java案例:
    看了很多文档和博客都没有找MongoTemplate关于操作lookup.let多条件关联查询的文档,
    所以在java案例中使用MongoClient 代替 MongoTemplate 查询。
*/

import com.mongodb.client.MongoClient;

@Autowired
private MongoClient mongoClient;

public void lookupLetTest(){
        Bson lookup = Aggregates.lookup(
                "parent22",  //关联从表的表名
                Arrays.asList( // 用来要作为筛选条件的字段
                        new Variable<>("Sname", "$name"),
                        new Variable<>("pName", "$parentName")
                ),
                Arrays.asList(
                        Aggregates.match(
                                Filters.eq("name","张1") // 筛选从表name等于‘张1’的信息,
                        ),
                        Aggregates.match(
                                Filters.expr(
                                        Filters.eq("$name","$$pName") // 筛选从表name等于主表parentName的信息
                                )
                        )

                ),
                "pr" //给结果起个别名
        );
        AggregateIterable<Map> aggregate = mongoClient.
                getDatabase("数据库名字").getCollection("表名字").aggregate(Arrays.asList(lookup), Map.class);

        for (Map map : aggregate) {
            
        }
    }


//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 :<arrayField>}

        介绍:            

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

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

         案例:

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

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

])

/**
未拆分的数据:
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"), 
    "name" : "张0", 
    "gender" : "女", 
    "age" : 0.0, 
    "math" : NumberInt(84), 
    "language" : NumberInt(99), 
    "classes" : "一年级二班", 
    "Hobby" : [
        "蓝色", 
        "蓝色1", 
        "蓝色2"
    ]
}


拆分后的数据:
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"), 
    "name" : "张0", 
    "gender" : "女", 
    "age" : 0.0, 
    "math" : NumberInt(84), 
    "language" : NumberInt(99), 
    "classes" : "一年级二班", 
    "Hobby" : "蓝色"
}
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"), 
    "name" : "张0", 
    "gender" : "女", 
    "age" : 0.0, 
    "math" : NumberInt(84), 
    "language" : NumberInt(99), 
    "classes" : "一年级二班", 
    "Hobby" : "蓝色1"
}
{ 
    "_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"), 
    "name" : "张0", 
    "gender" : "女", 
    "age" : 0.0, 
    "math" : NumberInt(84), 
    "language" : NumberInt(99), 
    "classes" : "一年级二班", 
    "Hobby" : "蓝色2"
}
**/

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

$geoNear

geoNear options>}

        介绍: 

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

        案例:参考这里

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

$bucket

        格式

        {         $bucket: {         groupBy: <expression>,         boundaries: [ <lowerbound1>, <lowerbound2>, ... ],         default: <literal>,          output: {         <output1>: { <$accumulator expression> },         <outputN>: { <$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<Test> result = mongoTemplate
                                       .aggregate(newAggregation, "你的表名", 实体类.class);
        //获取结果
        List<Test> mappedResults = result.getMappedResults();
}

springBoot整合mongoDB

        pom依赖

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

         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<Test> result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
        //获取结果
        List<Test> mappedResults = result.getMappedResults();
    }


---------------------------------mongoClient案例-----------------------------------------

//mongo查询语句
db.getCollection("table1").aggregate([
		{$lookup:{
		    from:"tabl2",
		     let: {
                pid: "$id"
            },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $eq: ["$$pid", "$disId"]
                        }
                    }
                },
                {$match:{dataType:{$eq:NumberInt(0)}}}
                ],
            as: "spotCheck",
		}},
		{$addFields:{spotCheckCount:{$size:"$spotCheck"}}},
		{$group:{_id:"$CREATEUSER",spotCheckCount:{$first:"$spotCheckCount"},createUser:{$first:"$CREATEUSER"},totalCount:{$sum:1}}}
])

//java代码
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCursor;
@Autowired
private MongoClient mongoClient;
@Autowired
private MongoConverter mongoConverter;

@Test
    public void test(){
        //关联查询
        Bson lookup = Aggregates.lookup(
                "table2",
                Arrays.asList(new Variable<>("disid", "$id")),
                Arrays.asList(
                        Aggregates.match(
                                Filters.expr(
                                        Document.parse("{$eq: ['$$pid', '$disId']}")
                                )),
                        Aggregates.match(
                                Filters.eq("dataType", 0)),
                        Aggregates.sort(Sorts.descending("abnormal"))
                ),
                "spotchecks");
           
        Bson addFields = Aggregates.addFields(
                Arrays.asList(
                        //获取数组的长度
                        new Field<>("spotCheckCount", Document.parse("{$size:'$spotCheck'}")),
                       
                        new Field<>("halfwayCheckCount", Document.parse("{$size:'$halfwayCheck'}"))
                )
        );
        //分组
        Bson group = Aggregates.group(
                "$CREATEUSER",
                Arrays.asList(
                        new BsonField("spotCheckCount", Document.parse("{$first:'$spotCheckCount'}")),
                        new BsonField("halfwayCheckCount", Document.parse("{$first:'$halfwayCheckCount'}")),
                        new BsonField("createUser",Document.parse("{$first:'$CREATEUSER'}")),
                        new BsonField("totalCount",Document.parse("{$first:'$CREATEUSER'}")),
                        new BsonField("createUser",Document.parse("{$sum:1}"))
                ));

        AggregateIterable<Document> aggregateResult =
                mongoClient
                        .getDatabase("数据库名")
                        .getCollection("表名")
                        .aggregate(
                                Arrays.asList(lookup, addFields, group));
        MongoCursor<Document> iterator = aggregateResult.iterator();
        while (iterator.hasNext()){
            //封装结果
            Map read = mongoConverter.read(Map.class, iterator.next());
        }

    }

Java操作MongoDB技巧:

       mongoDB的数学运算符,数组操作符,字符串操作符等,在java中大多都可以用

<xxx.运算符名称>的方式调用。


例如:

springboot如何判断mongodb集合一创建 spring data mongodb 聚合查询_数据库_02


注意引包: 都是

org.springframework.data.mongodb.core.aggregation.*包中的

springboot如何判断mongodb集合一创建 spring data mongodb 聚合查询_database_03


java操作mongodb的客户端有两个

org.springframework.data.mongodb.core.MongoTemplate @Autowired private MongoTemplate mongoTemplate; import com.mongodb.client.MongoClient; @Autowired private MongoClient mongoClient;

以上内容全部是介绍的MongoTemplate的操作方式

mongo文档1:腾讯mongo文档(中文) 

mongo文档2: mongo中文文档(内容全但是翻较差)