java mongodb 嵌套数组的更新与处理

4 篇文章 0 订阅

        最近我们的业务需求有增量更新,虽然后来考虑到复杂性,放弃了对嵌套文档的深嵌套更新,改为删除第一层嵌套再重新入。但嵌套更新的方法还是值得记录下来的。

        mongobd 集合的数据格式为

{
    "_id" : "123",
    "personCerts" : [ 
        {
            "perId" : "111",
            "perName" : "嘿嘿嘿",
            "certifications" : [ 
                {
                    "certNo" : "02333629",
                    "regType" : "072",
                    "regMajor" : "010"
                }
            ]
        }, 
        {
            "perId" : "222",
            "perName" : "哈哈哈",
            "certifications" : [ 
                {
                    "certNo" : "02333629",
                    "regType" : "071",
                    "regMajor" : "020"
                }
            ]
        }, 
        {
            "perId" : "333",
            "perName" : "呵呵呵",
            "certifications" : [ 
                {
                    "certNo" : "02345629",
                    "regType" : "021",
                    "regMajor" : "120"
                }, 
                {
                    "certNo" : "03445639",
                    "regType" : "041",
                    "regMajor" : "124"
                }
            ]
        }
    ],
    "createDate" : ISODate("2020-07-22T12:24:14.520Z"),
    "lastUpdate" : ISODate("2020-07-22T12:24:14.520Z")
}

在当前我们选择的更新方法之前,如果对上述文档进行更新要考虑很多方面。1.certifications里的数组变动更新 2.personCerts数组下的非certifications数组变动更新 3.单纯的 certifications 增加 4.单纯的 personCerts 增加

一.针对 certifications 里的数组变动更新,这个主要在于查询语句的写法,所有嵌套文档更新,如果需要嵌套关系,则必须使用elematch,这种更新方式在我之前的一篇博客中有写,主要是用 mongodb的 $[<identifier>]

如果我只想更新 perId = 333,certNo= 02345629 中的regMajor 为 000 ,mongo语句如下

db.getCollection("db_test").update(
    {
        $and: [
            {
                "_id": "1"
            },
            {
                "personCerts": {
                    $elemMatch: {
                        $and: [{
                            "perId": "333"
                        }, {
                            "certifications": {
                                "$elemMatch": {
                                    "certNo": "02345629"
                                }
                            }
                        }]
                    }
                }
            }
        ]
    },
    {
        $set: {
            "personCerts.$.certifications.$[certification].regMajor": "000"
        }
    },
    {
        arrayFilters: [{
            "certification.certNo": "02345629"
        }],
        multi: true
    }
)

java写法

Bson filters = Filters.and(Filters.eq("_id","1"),
                                Filters.elemMatch(
                                        "personCerts",
                                        Filters.and(
                                                Filters.eq("perId","333"),
                                                Filters.elemMatch("certifications",Filters.eq("certNo","02345629"))
                                        )
                                )
                        );
 
Bson update = Updates.set("personCerts.$.certifications.$[certification].regMajor","OOO");
        
Bson filter = Filters.eq("certification.certNo", "02345629");
        
UpdateOptions updateOptions = new UpdateOptions().arrayFilters(Collections.singletonList(filter));
 
MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("db_test");
 
documents.updateOne(filters,update,updateOptions);

二.针对personCerts数组下的非certifications数组变动更新。这回我想将perId = 111的 人员名称 perName 更新为 吼吼吼

这里也是用的 $[<identifier>] ,mongo写法如下

db.getCollection("db_test").update(
    
    {
        $and: [
            {
                "_id": "1"
            },
            {
                "personCerts": {
                    $elemMatch: {
                        "perId": "111"
                    }
                }
            }
        ]
    },
    {
        
        $set: {
            "personCerts.$[personCert].perName": "吼吼吼"
        }
    },
    {
        arrayFilters: [{
            "personCert.perId": "111"
        }],
        multi: true
    }
)

java写法

Bson filters = Filters.and(Filters.eq("_id","1"),
                                Filters.elemMatch(
                                        "personCerts",
                                        Filters.eq("perId","111")
                                )
                        );
 
Bson update = Updates.set("personCerts.$[personCert].perName","吼吼吼");
        
Bson filter = Filters.eq("personCert.perId", "111");
        
UpdateOptions updateOptions = new UpdateOptions().arrayFilters(Collections.singletonList(filter));
 
MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("db_test");
 
documents.updateOne(filters,update,updateOptions);

三.单纯的 certifications 增加 ,这属于嵌套数组的追加

db.getCollection("db_test").update(
    
    {
        $and: [
            {
                "_id": "1"
            },
            {
                "personCerts": {
                    $elemMatch: {
                        "perId": "111"
                    }
                }
            }
        ]
    },
    {
        $push: {
            "personCerts.$.certifications": {
                "certNo" : "34546546",
                "regType" : "546",
                "regMajor" : "433"
            }
        }
    },
    true
)

此处的push 如果用addToSet 代替的话,那么如果新加的数组元素与之前的相同,则不会新增,即addToSet 有去重的功能

java 写法

Map<String,Object> certification = new HashMap<>();
certification .put("certNo","34546546");
certification .put("regType","546");
certification .put("regMajor","433");

Bson filters = Filters.and(Filters.eq("_id","1"),
                                Filters.elemMatch(
                                        "personCerts",
                                        Filters.eq("perId","111")
                                )
                        );
 
Bson update = Updates.push("personCerts.$.certifications",certification);
 
MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("db_test");
 
collection.updateOne(filters,update,new UpdateOptions().upsert(true));

四.单纯的 personCerts 追加,这就很简单了

mngodb写法

db.getCollection("db_test").update(
    {
        $and: [
            {
                "_id": "1"
            }
        ]
    },
    {
        $addToSet: {
            "personCerts": {
				"perId": "444",
				"perName": "呵呵呵",
				"certifications": [
					{	
						"regMajor": "3453",
						"certNo": "7687"
						"regType": "43534"
					}
				]
			}
        }
    },
    true
)

java写法

Map<String,Object> personCerts = new HashMap<>();
personCerts.put("perId","444");
personCerts.put("perName","呵呵呵");

List<Map<String,Object>> certifications = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
map.put("regMajor":"3453");
map.put("certNo":"7687");
map.put("regType":"43534");

certifications.add(map);
personCerts.put("certifications",certifications);

Bson filters = Filters.eq("_id","1");
 
Bson update = Updates.push("personCerts",personCerts );
 
MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("db_test");
 
collection.updateOne(filters,update,new UpdateOptions().upsert(true));

 

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值