Mongo常用语法(java代码)

1、根据agentId字段分组,并对totalCustomerNum、refundCustomerNum字段 sum求和,同时取别名

    @Override
    public List<AgentCountInfoBean> selectCurrentMonthNewResource(Set<String> orderTypeSet, List<String> agentIds,
                                                                  LocalDateTime startTime, LocalDateTime endTime) {
        Aggregation aggr = newAggregation(
                match(where("agentId").in(agentIds)
                        .and("agentOrderType").in(orderTypeSet)
                        .and("agentOrderStatus").in(Arrays.asList(AgentOrderStatusEnum.NOT_START.status, AgentOrderStatusEnum.PROCESSING.status))
                        .andOperator(
                                EmptyUtils.isNotEmpty(startTime) ? Criteria.where("createTime").gte(startTime) : new Criteria(),
                                EmptyUtils.isNotEmpty(endTime) ? Criteria.where("createTime").lte(endTime) : new Criteria(), 
                                EmptyUtils.isNotEmpty(endTime) ? Criteria.where("hopeStartTime").lte(endTime) : new Criteria()
                        )
                ),
                group("agentId").first("agentId").as("agentId").sum("totalCustomerNum").as("totalCount")
                        .sum("refundCustomerNum").as("refundCustomerNum")
        );
        AggregationResults<AgentCountInfoBean> results = secondaryMongoTemplate.aggregate(aggr, ResAgentOrderMo.class, AgentCountInfoBean.class);
        if (EmptyUtils.isNotEmpty(results)) {
            return results.getMappedResults();
        }
        return null;
    }
                    

2、对agentId分组,并统计每个agentId分组后的个数,类似于mysql的select agentId,count(agentId) from tabel group by agentId;

    @Override
    public List<String> findNonFirstMonthBuyResource(LocalDateTime startDate, List<String> leadingEagleIds, Set<String> agentOrderSetsT) {
        Aggregation aggr = newAggregation(
                match(where("agentId").in(leadingEagleIds)
                        .and("agentOrderType").in(agentOrderSetsT)
                        .and("agentOrderStatus").ne(AgentOrderStatusEnum.NOT_PAY.status)
                        .andOperator(
                                EmptyUtils.isNotEmpty(startDate) ? Criteria.where("payTime").lte(startDate) : new Criteria()
                        )
                ),
                group("agentId").first("agentId").as("agentId").count().as("count")
        );
        AggregationResults<AgentCountBean> results = secondaryMongoTemplate.aggregate(aggr, ResAgentOrderMo.class, AgentCountBean.class);
        if (EmptyUtils.isNotEmpty(results)) {
            return results.getMappedResults().stream().map(AgentCountBean::getAgentId).collect(Collectors.toList());
        }
        return null;
    }

3、根据条件查询,然后只返回某个字段同时去重

    @Override
    public List<String> findNotEndAgentIdsByTypeAndSaleAreas(Set<String> agentOrderTypes, List<String> areaIds) {
        Query query = query(
                where("agentOrderType").in(agentOrderTypes)
                        .and("agentOrderStatus").in(Arrays.asList(AgentOrderStatusEnum.NOT_START.status, AgentOrderStatusEnum.PROCESSING.status))
                        .and("hopeStartTime").lte(LocalDateTime.now())
                        .and("notMatchCustomerNum").gt(0)
                        .andOperator(EmptyUtils.isNotEmpty(areaIds) ? Criteria.where("areaId").in(areaIds) : new Criteria())
        );
        return secondaryMongoTemplate.findDistinct(query, "agentId", ResAgentOrderMo.class, String.class);
    }

4、根据两个字段分组,同时根据某个字段排序

    @Override
    public List<AgentOrderBcVo> findFirstOrder(String agentId) {
        Criteria criteria = new Criteria();
        // 排除每日抢领活动
        criteria.and("agentOrderType").ne(AgentOrderTypeEnum.DAILY_GRABBING.type);
        criteria.and("notMatchCustomerNum").gt(0);
        criteria.and("agentId").is(agentId);
        criteria.orOperator(
                Criteria.where("agentOrderStatus").is(AgentOrderStatusEnum.NOT_START.status),
                Criteria.where("agentOrderStatus").is(AgentOrderStatusEnum.PROCESSING.status)
        );
        List<AggregationOperation> operations = new ArrayList<>();
        operations.add(Aggregation.match(criteria));
        Sort sort = Sort.by(Sort.Direction.ASC, "hopeStartTime");
        //按照期望开始时间正序
        operations.add(Aggregation.sort(sort));
        operations.add(Aggregation.group("agentOrderType", "agentOrderDesc")
                .first("_id").as("agentOrderId").first("payTime").as("payTime").first("agentOrderType").as("agentOrderType")
                .first("agentOrderDesc").as("agentOrderDesc")
                .first("agentName").as("agentName").first("phoneNumber").as("phoneNumber").first("buyCustomerNum").as("buyCustomerNum")
                .first("giveCustomerNum").as("giveCustomerNum").first("couponCustomerNum").as("couponCustomerNum").first("payType").as("payType")
                .first("payPrice").as("payPrice").first("agentOrderStatus").as("agentOrderStatus").first("areaName").as("areaName")
                .first("hopeCity").as("hopeCity").first("hopeStartTime").as("hopeStartTime").first("totalCustomerNum").as("totalCustomerNum")
                .first("notMatchCustomerNum").as("notMatchCustomerNum")
        );
        sort = Sort.by(Sort.Direction.DESC, "notMatchCustomerNum");
        //按累计未分配客户数量排序
        operations.add(Aggregation.sort(sort));
        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<AgentOrderBcVo> aggregate = secondaryMongoTemplate.aggregate(aggregation, "agentOrderMo", AgentOrderBcVo.class);
        return aggregate.getMappedResults();
    }

其中first用法是,分组时对于多条数据取第一条的数据的相关字段
5、根据某个字段分组,对某个字段求和以后,然后再筛选,类似于mysql的 select type, sum(price) as count from table group by type having count >10

    @Override
    public List<String> filterByWeekAndMonthAndDay(String target, List<String> businessModels, String pastMonth, int monthNum,int weekNum,int dayNum,List<String> agentIds) {
        Aggregation aggregation = newAggregation(
                Aggregation.match(where("businessModel").in(businessModels)
                        .and("pastMonth").is(pastMonth)
                        .and("target").is(target)
                        .and("agentId").in(agentIds)
                        .and("isDeleted").is(false)),
                Aggregation.group("agentId").first("agentId").as("agentId").sum("thisMonthNum").as("monthMatchSumNum")
                        .sum("thisWeekNum").as("weekMatchSumNum").sum("todayNum").as("dayMatchSumNum"),
                Aggregation.match(where("monthMatchSumNum").lt(monthNum).and("weekMatchSumNum").lt(weekNum).and("dayMatchSumNum").lt(dayNum))
        );
        AggregationResults<AgentIdAndMatchNumBean> aggregate = secondaryMongoTemplate.aggregate(aggregation, ResDacMatchAgentWeightMo.class, AgentIdAndMatchNumBean.class);
        if (EmptyUtils.isNotEmpty(aggregate)) {
            List<AgentIdAndMatchNumBean> results = aggregate.getMappedResults();
            return results.stream().map(AgentIdAndMatchNumBean::getAgentId).collect(Collectors.toList());
        }
        return null;
    }

6、match, group,sort,limit一起使用

    @Override
    public List<AgentWeightBean> findSortByAgentIds(List<String> agentIds, List<String> targets, List<String> targetExtras, String businessModel, String pastMonth, int limit) {
        Aggregation aggr = newAggregation(
                match(where("agentId").in(agentIds)
                        .and("businessModel").is(businessModel)
                        .and("pastMonth").is(pastMonth)
                        .orOperator(
                                EmptyUtils.isNotEmpty(targets) ? Criteria.where("target").in(targets) : Criteria.where("target").is(""),
                                EmptyUtils.isNotEmpty(targetExtras) ? Criteria.where("targetExtra").in(targetExtras) : Criteria.where("targetExtra").is("")
                        )
                        .and("isDeleted").is(false)
                ),
                group("agentId").first("agentId").as("agentId").sum("weight").as("weight"),
                sort(Sort.by(Sort.Direction.DESC,"weight")),
                limit(limit)
        );
        AggregationResults<AgentWeightBean> results = secondaryMongoTemplate.aggregate(aggr, ResDacMatchAgentWeightMo.class,AgentWeightBean.class);
        return results.getMappedResults();
    }

7、更新操作

    @Override
    public void updateTarget(String agentId, List<String> targets, List<String> targetExtras, String businessModel, String pastMonth) {

        Query query = query(where("agentId").is(agentId)
                .and("businessModel").is(businessModel)
                .and("pastMonth").is(pastMonth)
                .orOperator(
                        EmptyUtils.isNotEmpty(targets) ? Criteria.where("target").in(targets) : Criteria.where("target").is(""),
                        EmptyUtils.isNotEmpty(targetExtras) ? Criteria.where("targetExtra").in(targetExtras) : Criteria.where("targetExtra").is("")
                )
                .and("isDeleted").is(false)
        );
        Update update =  update("updateTime",LocalDateTime.now())
        		//inc是自增操作,原子性操作
                .inc("todayNum",1)
                .inc("thisWeekNum",1)
                .inc("twoWeekNum",1)
                .inc("thisMonthNum",1)
                .inc("weight",-0.08);

        secondaryMongoTemplate.updateMulti(query,update,ResDacMatchAgentWeightMo.class);
    }

8、聚合查询时对多个字段进行运算符操作,比如 sum,divide

    @Override
    public List<ReportAgentBean> getReportDataByAId(String aId, String aIdType, String reportType, String reportDate) {
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and("aIdType").is(aIdType);
        criteria.and("reportType").is(reportType);
        criteria.and("aId").is(aId);
        criteria.and("reportDate").is(reportDate);
        query.addCriteria(criteria);

        Aggregation aggregation = newAggregation(
        		//project表示需要用到那些字段,返回那些字段
                Aggregation.project(PROJECT_FIELDS)
                        //总标化保费
                        .and(this.totalCriterionAmountExpression()).as("totalCriterionAmount")
                        //成交服务单均保费
                        .and(this.averageIssueAmountExpression()).as("averageIssueAmount")
                        //件均保费
                        .and(this.averageAmountExpression()).as("averageAmount")
                        .and(this.totalAmountExpression()).as("totalAmount")
                        .and(this.pmAgentNumRateExpression()).as("pmAgentNumRate")
                ,
                Aggregation.match(criteria),
                Aggregation.sort(Sort.by(Sort.Direction.DESC, "totalCriterionAmount"))
        );
        AggregationResults<ReportAgentBean> results = mongoTemplate.aggregate(aggregation, ReportAgentDataMo.class, ReportAgentBean.class);
        return results.getMappedResults();
    }

	
    private static final String[] PROJECT_FIELDS = {"id", "aIdType", "aId", "reportDate", "reportType", "advanceCriterionAmountDacT", "advanceNumDacT",
            "advanceAmountDacT", "buyCustDacT", "giveCustDacT", "matchDacT", "upToStandardNum",
            "pmDacT", "nonPmDacT", "policyConfirmNumDacT", "policyConfirmOrderNumDacT",
            "upToStandardAgentNum", "dealInternetAmountDacT", "dealLifeAmountDacT",
            "dealLifeCriterionAmountDacT", "dealHighAmountDacT", "dealCarAmountDacT", "dealGroupAmountDacT",
            "dealHighCriterionAmountDacT", "dealCarCriterionAmountDacT", "dealGroupCriterionAmountDacT", "digitalAgentNum",
            "dealInternetNumDacT", "dealLifeNumDacT", "dealHighNumDacT", "dealCarNumDacT", "cashCoupon", "cashCouponAmount",
            "dealGroupNumDacT", "createTime"};

    //totalCriterionAmountExpression这个方法返回的数据5个字段相加后的结果
    private AggregationExpression totalCriterionAmountExpression() {
        return ArithmeticOperators.Add.valueOf("dealInternetAmountDacT")
                .add("dealHighCriterionAmountDacT")
                .add("dealCarCriterionAmountDacT")
                .add("dealGroupCriterionAmountDacT")
                .add("dealLifeCriterionAmountDacT");
    }
	//averageIssueAmountExpression这个方法会拿到totalCriterionAmountExpression方法的返回值然后和policyConfirmNumDacT字段相除
    private AggregationExpression averageIssueAmountExpression() {
        AggregationExpression totalCriterionAmount = this.totalCriterionAmountExpression();
        return ConditionalOperators.when(new Criteria("policyConfirmNumDacT").ne(0))
                .thenValueOf(ArithmeticOperators.Divide.valueOf(totalCriterionAmount).divideBy("policyConfirmNumDacT"))
                .otherwise(0);
    }

9、聚合查询时的分页查询

    @Override
    public List<ReportAgentBean> digitalAgentQuery(PageMsg pageMsg) {
        Criteria criteria = new Criteria();
        criteria.and("aIdType").is(AIdTypeEnum.agent.name());
        criteria.and("reportType").is(ReportTypeEnum.TOTAL.type);
        //累计服务单数 大于等于30
        criteria.and("digitalSvNum").gte(DigitalLevelEnum.digital_1.matchDacT);
        //标化总保费大于 5W
        criteria.and("digitalPolicyPerformance").gte(DigitalLevelEnum.digital_1.totalCriterionAmount);
        //累计成交订单数 大于5
        criteria.and("digitalTurnoverPerformance").gte(DigitalLevelEnum.digital_1.policyConfirmNumDacT);

        Aggregation aggregation = newAggregation(
                Aggregation.match(criteria),
                Aggregation.project(DIGITAL_FIELDS)
                        //总标化保费
                        .and("digitalPolicyPerformance").as("totalCriterionAmount")
                        .and("digitalSvNum").as("matchDacT")
                        .and("digitalTurnoverPerformance").as("policyConfirmNumDacT")
                ,
                Aggregation.sort(Sort.by(Sort.Direction.DESC, "totalCriterionAmount")),
                Aggregation.skip((long) (pageMsg.getPageNum() - 1) * pageMsg.getPageSize()),
                Aggregation.limit(pageMsg.getPageSize())
        );
        AggregationResults<ReportAgentBean> results = mongoTemplate.aggregate(aggregation, ReportAgentDataMo.class, ReportAgentBean.class);
        return results.getMappedResults();
    }
<think>好的,我现在需要回答用户关于如何在Java中使用MongoDB进行批量更新的问题。首先,我要确认用户的需求:他们想要示例代码,说明如何实现批量更新操作。用户可能已经了解MongoDB的基本操作,但需要具体的Java代码示例。 接下来,我应该回忆MongoDB的Java驱动程序和常用的操作方法。记得MongoTemplate是Spring Data MongoDB的一部分,它提供了方便的操作方法。同时,MongoDB本身支持批量操作,比如bulkWrite,这可能涉及到BulkOperations类。 然后,我需要检查用户提供的引用内容。引用[2]提到了db.collection.bulkWrite()方法,可以用于批量插入、更新和删除。引用[3]中有一个Java代码示例,使用mongoTemplate.bulkOps来创建BulkOperations实例,然后进行插入操作。这说明用户可能在使用Spring Data MongoDB,所以示例代码应该基于这个库。 接下来,我需要构建一个示例代码,展示如何执行批量更新。步骤可能包括:获取BulkOperations实例,添加多个更新操作,然后执行批量操作。需要注意不同更新类型,比如更新多个文档或单个文档,使用Update.update来设置字段值。 此外,需要确保代码语法正确,比如正确导入类,处理异常等。还要提醒用户关于BulkMode.ORDERED和UNORDERED的区别,以及性能方面的考虑,比如批量操作的大小限制。 可能还需要考虑是否需要使用upsert选项,或者如何处理更新条件。示例中应该包含具体的更新条件,比如根据某个字段匹配文档,然后更新另一个字段的值。 最后,总结使用批量更新的好处,比如减少网络开销,提高性能,并指出相关引用来源,确保引用标识正确对应。</think>以下是使用Java操作MongoDB实现批量更新的两种实现方式及详细说明: --- ### 方法一:使用BulkOperations批量操作(推荐) ```java // 获取MongoTemplate实例(Spring Data MongoDB) BulkOperations bulkOps = mongoTemplate.bulkOps( BulkOperations.BulkMode.UNORDERED, // 无序执行提升性能 "your_collection_name" // 集合名称 ); // 添加批量更新操作 List<Update> updates = new ArrayList<>(); updates.add( new Update().set("status", "active") // 设置字段值 .filter(Criteria.where("age").gt(18)) // 过滤条件:age>18 ); updates.add( new Update().inc("login_count", 1) // 自增字段 .filter(Criteria.where("role").is("user")) ); // 批量执行更新(可混合插入/删除操作) bulkOps.updateMulti(updates); // updateMulti表示更新所有匹配文档 BulkWriteResult result = bulkOps.execute(); // 执行操作 System.out.println("影响文档数:" + result.getModifiedCount()); ``` **特性说明**: - 支持混合$插入、更新、删除$操作[^2] - `BulkMode.UNORDERED`表示忽略执行顺序错误 - 单次批量操作建议控制在1000个以内以避免内存压力[^3] --- ### 方法二:直接使用BulkWrite(原生驱动) ```java MongoCollection<Document> collection = mongoDatabase.getCollection("your_collection_name"); List<WriteModel<Document>> bulkWrites = new ArrayList<>(); bulkWrites.add( new UpdateManyModel<>( Filters.eq("category", "electronics"), // 过滤条件 Updates.set("discount", 0.1) // 更新动作 ) ); bulkWrites.add( new UpdateOneModel<>( Filters.eq("product_id", 1001), Updates.combine(Updates.set("price", 599), Updates.currentDate("update_time")) ) ); BulkWriteResult result = collection.bulkWrite(bulkWrites); // 默认有序执行 System.out.println("更新数量:" + result.getModifiedCount()); ``` **特性说明**: - 需通过`Filters`和`Updates`工具类构建条件 - 支持$UpdateManyModel$(更新多个)和$UpdateOneModel$(更新单个) - 原生API更接近MongoDB语法结构[^1] --- ### 性能优化建议 1. 优先选择**无序批量操作**(UNORDERED)以提升吞吐量 2. 单个批量操作建议包含**100-1000个操作**,过多会导致内存压力 3. 使用`$set`等原子操作符替代全文档替换 4. 对频繁更新字段建议建立索引(如示例中的`age`字段) 两种方式均能实现高效批量更新,Spring Data MongoDB的封装更简洁,而原生驱动灵活性更高。实际开发中若已使用Spring框架,推荐第一种方式。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值