使用MongoTemplate批量更新内嵌数组元素

原生Mongo从3.6以上可以使用$[<identifier>]操作符批量修改内嵌数组元素,以下是基于mongoTemplate的封装实现:

/**
 * MonogoDB 更新操作符
 */
@Getter
@AllArgsConstructor
public enum UpdateOperator {
    //
    INC("$inc"),
    SET("$set");

    String code;
}

/**
     * 更新内嵌数组指定元素
     *
     * @param query         更新的文档查询条件
     * @param arrayName     更新的内嵌数组名
     * @param updateMap    对内嵌数组元素不同操作的更新map
     * @param eleFilter 更新内嵌数组元素的过滤条件
     * @return
     */
public UpdateResult updateArrayElement(Criteria query, String arrayName, Map<UpdateOperator, JSONObject> updateMap, Criteria eleFilter){
        BasicDBObject update = new BasicDBObject();
        UpdateOptions updateOptions = new UpdateOptions();

        // 设置$set和$inc等操作符对应的元素更新
        for (UpdateOperator operator : updateMap.keySet()){
            BasicBSONObject eleSetBson = new BasicBSONObject();
            JSONObject eleSetJson = updateMap.get(operator);
            for (String key : eleSetJson.keySet()){
                eleSetBson.put(arrayName.concat(".$[item].").concat(key), eleSetJson.get(key));
            }
            update.put(operator.getCode(), eleSetBson);
        }

        BasicDBObject eleFilterBson = new BasicDBObject();
        Document filter = eleFilter.getCriteriaObject();
        for (String key : filter.keySet()){
            eleFilterBson.put("item.".concat(key), filter.get(key));
        }
        updateOptions.arrayFilters(Lists.newArrayList(eleFilterBson));
        return mongoTemplate.getCollection(tabName).updateMany(
                query.getCriteriaObject(),
                update,
                updateOptions
        );
    }

假设有以下数据,实现将"_id":"id"文档中sex为1的des设为"男",age加2:

{
	"_id":"id",
	"users":[
		{
			"uid":2,
			"sex":1,
			"age":23,
			"des":"",
			"name":"Alex"
		},
		{
			"uid":3,
			"sex":1,
			"age":33,
			"des":"",
			"name":"Bob"
		},
		{
			"uid":4,
			"sex":0,
			"age":20,
			"des":"",
			"name":"Cat"
		},
	]
}
public void demo(){
        Map<UpdateOperator, JSONObject> updateMap = new HashMap<>();
        JSONObject setJson = new JSONObject();
        JSONObject incJson = new JSONObject();
        setJson.put("des", "男");
        incJson.put("age", 2);
        updateMap.put(UpdateOperator.SET, setJson);
		updateMap.put(UpdateOperator.INC, incJson );
        // 批量设置用户的状态
        updateArrayElement(
            Criteria.where("_id").is("id"),
            "users",
            updateMap,
            Criteria.where("sex").is(1)
        );
    }
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值