mongo增加count统计以及seq顺序号节点、查重

本文展示了如何在MongoDB中进行数据操作,包括为每个学生文档添加科目数和seqNo字段,并通过聚合查询找出具有相同科目数的学生人数和详细信息。实现了对数据的动态更新和统计分析,为后续的数据处理提供了便利。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现存数据:三个学生的学号,姓名及科目考试信息,其中科目是一个集合数组文档,具体数据如下:

{ 
    "_id" : ObjectId("6009179ac73cb830a50c9520"), 
    "idNo" : "00001", 
    "name" : "jack", 
    "major" : [
        {
            "cName" : "马克思理论", 
            "cCode" : "0.001", 
            "type" : "1", 
            "core" : "90", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "mongo", 
            "cCode" : "2.001", 
            "type" : "2", 
            "core" : "100", 
            "date" : "2021-01-11 11:00:00"
        }
    ]
}
{ 
    "_id" : ObjectId("6009179ac73cb830a50c9521"), 
    "idNo" : "00008", 
    "name" : "tom", 
    "major" : [
        {
            "cName" : "PS", 
            "cCode" : "10.001", 
            "type" : "1", 
            "core" : "90", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "PS", 
            "cCode" : "10.002", 
            "type" : "1", 
            "core" : "90", 
            "date" : "2021-01-21 12:00:00"
        }
    ]
}
{ 
    "_id" : ObjectId("6009179ac73cb830a50c9522"), 
    "idNo" : "00009", 
    "name" : "Jerry", 
    "major" : [
        {
            "cName" : "影视", 
            "cCode" : "11.001", 
            "type" : "2", 
            "core" : "100", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "mongo", 
            "cCode" : "2.001", 
            "type" : "2", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "动漫", 
            "cCode" : "7.001", 
            "type" : "1", 
            "core" : "88", 
            "date" : "2021-01-21 12:00:00"
        }
    ]
}
{ 
    "_id" : ObjectId("6009179ac73cb830a50c9344"), 
    "idNo" : "00010", 
    "name" : "Rose", 
    "major" : [
        {
            "cName" : "影视", 
            "cCode" : "11.001", 
            "type" : "2", 
            "core" : "100", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "mongo", 
            "cCode" : "2.001", 
            "type" : "2", 
            "core" : "88", 
            "date" : "2021-01-21 12:00:00"
        }, 
        {
            "cName" : "动漫", 
            "cCode" : "7.001", 
            "type" : "1", 
            "core" : "66", 
            "date" : "2021-01-21 12:00:00"
        }
    ]
}

  • 现有需求1,给每个学生添加科目数以及每个科目增加seqNo顺序号

实现思路:先循环每个学生拿到科目集合数组,再去循环科目,增加seqNo节点

实现代码:

db.getCollection("test").find({}).forEach(function (item) {
    var array = item.major;    // 科目集合 
    item.count=array.length; // 科目数
    array.forEach(function (ele, index) {
        ele.seqNo = (index + 1) + "";     // index为节点ele下标,从0开始
        db.getCollection('test').save(item) // 更新数据
    })
})

实现结果:

{ 
    "_id" : ObjectId("6009179ac73cb830a50c9520"), 
    "idNo" : "00001", 
    "name" : "jack", 
    "major" : [
        {
            "cName" : "马克思理论", 
            "cCode" : "0.001", 
            "type" : "1", 
            "core" : "90", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "1"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "2"
        }, 
        {
            "cName" : "mongo", 
            "cCode" : "2.001", 
            "type" : "2", 
            "core" : "100", 
            "date" : "2021-01-11 11:00:00", 
            "seqNo" : "3"
        }
    ], 
    "count" : 3.0
}
{ 
    "_id" : ObjectId("6009179ac73cb830a50c9521"), 
    "idNo" : "00008", 
    "name" : "tom", 
    "major" : [
        {
            "cName" : "PS", 
            "cCode" : "10.001", 
            "type" : "1", 
            "core" : "90", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "1"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "2"
        }, 
        {
            "cName" : "PS", 
            "cCode" : "10.002", 
            "type" : "1", 
            "core" : "90", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "3"
        }
    ], 
    "count" : 3.0
}
{ 
    "_id" : ObjectId("6009179ac73cb830a50c9522"), 
    "idNo" : "00009", 
    "name" : "Jerry", 
    "major" : [
        {
            "cName" : "影视", 
            "cCode" : "11.001", 
            "type" : "2", 
            "core" : "100", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "1"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "2"
        }, 
        {
            "cName" : "mongo", 
            "cCode" : "2.001", 
            "type" : "2", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "3"
        }, 
        {
            "cName" : "动漫", 
            "cCode" : "7.001", 
            "type" : "1", 
            "core" : "88", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "4"
        }
    ], 
    "count" : 4.0
}
{ 
    "_id" : ObjectId("6009179ac73cb830a50c9344"), 
    "idNo" : "00010", 
    "name" : "Rose", 
    "major" : [
        {
            "cName" : "影视", 
            "cCode" : "11.001", 
            "type" : "2", 
            "core" : "100", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "1"
        }, 
        {
            "cName" : "java并发编码", 
            "cCode" : "1.001", 
            "type" : "1", 
            "core" : "80", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "2"
        }, 
        {
            "cName" : "mongo", 
            "cCode" : "2.001", 
            "type" : "2", 
            "core" : "88", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "3"
        }, 
        {
            "cName" : "动漫", 
            "cCode" : "7.001", 
            "type" : "1", 
            "core" : "66", 
            "date" : "2021-01-21 12:00:00", 
            "seqNo" : "4"
        }
    ], 
    "count" : 4.0
}

  • 现有需求2,查出相同科目数的学生人数

 实现思路:在数据库里可以换个角度思考需求的意思,实际上可以理解为根据科目数分组,那么就可以使用聚合函数aggregate实现统计 

实现代码:

db.getCollection('test').aggregate(
    {
        '$group': {
            '_id': {                    //_id 即分组条件
                'majorCount': '$count'     // 根据count分组
            },
            'count': { '$sum': 1 }        // 统计count的相同的学生人数
        }
    },
    {
        '$match': {
            'count': { '$gt': 1 }        //将分组后的数据,进行过滤
        }
    }
) 

实现结果:4个科目数的有2人,3个科目数的有2人

{ 
    "_id" : {
        "majorCount" : 4.0
    }, 
    "count" : 2.0
}
{ 
    "_id" : {
        "majorCount" : 3.0
    }, 
    "count" : 2.0
}
  • 现有需求3,查出相同科目数的学生姓名,学号

实现思路:在需求2的实现基础上,遍历查询学生姓名,学号

实现代码:

db.getCollection('test').aggregate(
    {
        '$group': {
            '_id': {                    //_id 即分组条件
                'majorCount': '$count'     // 根据count分组
            },
            'count': { '$sum': 1 }        // 统计count的相同的学生人数
        }
    },
    {
        '$match': {
            'count': { '$gt': 1 }        //将分组后的数据,进行过滤
        }
    }
).forEach(function (item) {
    print("科目数为" + item._id.majorCount + "的学生是:\n")
    var cursor = db.getCollection("test").find(
        {
            'count': item._id.majorCount
        });
    var doc = null;
    while (cursor.hasNext()) {
        doc = cursor.next();
        if (doc != null) {
            print(doc.idNo + "\t" + doc.name + "\n")
        }
    }
    doc = null;
}
)

实现效果:

### 使用 `MongoTemplate` 实现 MongoDB 分组聚合操作 为了实现基于 `MongoTemplate` 的分组聚合查询,可以利用 Spring Data MongoDB 提供的强大功能。下面是一个具体的例子,展示如何通过 Java 代码执行这样的操作。 #### 构建 Aggregation Pipeline 首先定义匹配条件(如果有的话),接着指定要进行的操作如 `$group`, 并设置所需的累积表达式来计算汇总值: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.stereotype.Service; @Service public class StentService { @Autowired private MongoTemplate mongoTemplate; public List<StentSummary> getLatestStentData() { MatchOperation match = Aggregation.match(Criteria.where("status").is("active")); // 可选的过滤条件 GroupOperation group = Aggregation.group("stentId") .first("$$ROOT") // 获取每个 stentId 下的第一条记录 (按 createdAt 排序后的第一条) .as("latestRecord"); SortOperation sortWithinGroup = Aggregation.sort(Sort.Direction.DESC, "createdAt"); ProjectionOperation projection = Aggregation.project() .andExpression("_id").as("stentId") .andExpression("latestRecord.createdAt").as("lastUpdatedDate") .andExpression("latestRecord.status").as("currentStatus"); Aggregation aggregation = Aggregation.newAggregation( match, sortWithinGroup, group, projection); AggregationResults<StentSummary> results = mongoTemplate.aggregate(aggregation, "stents", StentSummary.class); return results.getMappedResults(); } } ``` 这段代码展示了怎样创建一个包含多个阶段的聚合管道[^2]。这里先进行了简单的状态筛选(`match`),再按照创建日期降序排列(`sort`)以确保能取到最新的那一条记录作为代表;之后使用了`$group`命令来进行实际的数据分组处理,并最终投影出所需的结果字段[^1]。 对于上述代码片段中的实体类 `StentSummary` ,其结构应该反映所期望返回的对象模型: ```java @Data @NoArgsConstructor @AllArgsConstructor class StentSummary { String stentId; Date lastUpdatedDate; String currentStatus; } ``` 此方法能够有效地获取每一个支架编号下最近一次更新的信息摘要[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值