添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

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"

此处的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"

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));
最近我们的业务需求有增量更新,虽然后来考虑到复杂性,放弃了对嵌套文档的深嵌套更新,改为删除第一层嵌套再重新入。但嵌套更新的方法还是值得记录下来的。 mongobd 集合的数据格式为{ "_id" : "123", "personCerts" : [ { "perId" : "111", "perName" : "嘿嘿嘿", "certifications" : [...
一、更新数组中的值 看如下students文档中的数据: db.students.insert({_id:NumberInt(1),grades:[NumberInt(80),NumberInt(85),NumberInt(90)]}) db.students.insert({_id:NumberInt(2),grades:[NumberInt(88),NumberInt(90),Number
SpringBoot使用MongoTemplate动态切换Mongo     当前有一个项目包含一套代码和1个mongo的数据库,但要给2个部门用户使用,而且要做数据隔离,现有做法是部署2套代码和2个mongo数据库,2个域名,这样就能各自访问各自的系统,做到隔离。但为节省资源和减少运维工作,计划将2个系统合并为一个系统,一套代码部署,2个数据库。那么如何使用最少的成本完成系统升级呢。
我!!!永远!!!为!!!爆栈!!!打call!!! 当初使用mongo时,没用过多考虑更新的问题,采取了双层嵌套格式的来存储数据,现在需求变动,要有更新,百度了一天,没有解决,爆哭,尝试在爆栈搜索解决方法,又又又又一次,爆栈救了我的命!!! 我的文档格式 "_id" : "1", "personCerts" : [ "perId" : "546", "perName" : "老坛酸菜",
1、普通更新 DBObject queryCondition = new BasicDBObject(); queryCondition.put("patient_id", patientId); DBObject setValue = new BasicDBObject(); //mongo存储路径 /see_face_image/1515477094127/111.jpg String sa...
对于数组对象mongodb本身是支持的,不过对于数组更新mongodb的Csharp驱动目前只支持一级,即你的对象里包含数组,而数组又包括数组,这表示两层,这在更新数组时,Csharp驱动是不支持的,今天要说的就是如何让它支持子数组更新,下面是我给出的数据结构 在Mongodb的Csharp驱动里,一般的更新方法如下 update = new UpdateDoc...
db.collection.updateOne( { _id: ObjectId("xxx") }, { $set: { "arrayField.1": "new value" } } 这个例子中,我们将数组字段 arrayField 中索引为 1 的元素修改为 "new value"。