MongoDB數組修改器更新數據

MongoDB數組修改器更新數據
   這裏,我們將瞭解一下數組修改器。數組,是我們經常看到和使用到的且非常有用的數據結構:它不僅可以通過索進行引用,還可以作爲集合來使用。數組修改器,顧名思義,它是用來修改數組的,而不能用來修改整數或者字符串。數組修改器不多,就那麼幾個,但熟練掌握它後,將給我們帶來非常方便的操作。下面,我們來了解一下:
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "deng",
            "lname" : "pan"
        },
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "dongren",
            "lname" : "zeng"
        }
    ]
}
以上是我的還在完善中的個人信息文檔。假設最近我又交了一個好朋友,我想把他加到我的人際關係“relationships”數組中。這時,$push修改器就派上用場了。$push的作用就是,如果指定的鍵已經存在,它會向已有的數組末尾加入一個元素,要是沒有就會創建一個新的數組。下面我們把新朋友加進去。
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$push:{"relationships":{"fname":"xiong","lname":"lan"}}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "deng",
            "lname" : "pan"
        },
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "dongren",
            "lname" : "zeng"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        }
    ]
}
有加就有減,那麼怎麼對數組進行“減”操作呢。能達到對數組“減”目的的修改器有兩個,$pop和$pull。$pop和$pull又有區別,我們來分別實驗。首先是$pop
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pop:{"relationships":1}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "deng",
            "lname" : "pan"
        },
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "dongren",
            "lname" : "zeng"
        }
    ]
}
從上面可以看出,它把我們剛加進去的朋友又刪除了,也就是說它從數組的最後刪除。那麼,如果我們想從數組的開頭刪除該怎麼辦呢。很簡單,把上面的“1”改成“-1”,它將逆向操作。下面看一下:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pop:{"relationships":-1}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "dongren",
            "lname" : "zeng"
        }
    ]
}
從結果可以看出,它達到了我們預期的目的。那麼如果我們想刪除數組中間的呢。這時,$pull派上用場。首先,我們先將新朋友加進去,這裏我不再演示。但我們可以想到“dongren”這個人是在數組的中間。現在我們要將他刪除:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pull:{"relationships":{"fname":"dongren","lname":"zeng"}}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        }
    ]
}
從上面可以看出,$pull可以將數組中間的數據刪除。這裏還有一點要注意,$pull會將所有匹配到的數據都刪除,這裏我就不做實驗了。下面,我們再來看看$push還有什麼特點,我們再往數組裏插入一相同的數據,看看會如何:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$push:{"relationships":{"fname":"xiong","lname":"lan"}}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        }
    ]
}
結果表明,它是能正常插入到數組的。而在實際生產環境中,我們都不想看到這樣的結果,那麼,這裏又出現了兩個可以用的修改器:$ne和$addToSet。$ne主要拿來判斷,若數組裏面有這個值,則不插入;沒有才插入。
> db.user.update({"relationships.fname":{$ne:"xiong"}},{$set:{"fname":"xiong","lname":"lan"}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        }
    ]
}
由結果可以看出,由於該數據在數組中已經存在,所以不再插入。其實,$addToSet比$ne更好用,它可以自己判斷數據是否存在,而且它和$each結合使用,還能同時在數組中插入多個數據,這是$ne沒辦法辦到的,下面我們來看一下$addToSet的用法,這裏順便結合了$each的使用:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},
{$addToSet:{"relationships":{$each:[{"fname":"xiong","lname":"lan"},
{"fname":"dongren","lname":"zeng"}]}}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        },
        {
            "fname" : "dongren",
            "lname" : "zeng"
        }
    ]
}
在修改語句中,我們想同時插入{"fname":"xiong","lname":"lan"},
{"fname":"dongren","lname":"zeng"}兩個數據,但在原數組中,
{"fname":"xiong","lname":"lan"}這個數據已經存在,所以它只插入了後面那條。達到了我們想要的目的。所以,我個人更喜歡使用$addToSet。
    有時候數組有多個值,而我們只想對其中的一部分進行操作。如果我們把整個文檔都抄下來,那太麻煩也太愚蠢了。好在mongodb給我們提供了兩種簡便方法:通過位置或者操作符“$”。下面我們來分別看看這兩種方法怎麼使用。首先是通過數組位置來操作。數組都是以0開頭的,可以將下標直接作爲鍵來選擇元素。例如,我們想給數組的第一個數據加上年齡鍵值對,我們可以這麼操作:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$set:{"relationships.0.age":22}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "age" : 22,
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "fname" : "deng",
            "lname" : "pan"
        },
        {
            "fname" : "xiong",
            "lname" : "lan"
        }
    ]
}
可是很多情況下,不預先查詢文檔我們就不知道要修改數組的元素的下標。這時定位操作符“$”就很好用了。它就是用來定位查詢文檔已匹配的元素,並進行更新。我們來看看它怎麼用:
> db.user.update({"relationships.fname":"xiong"},{$set:{"relationships.$.age":22}})
> db.user.findOne()
{
    "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),
    "age" : 23,
    "favorite" : {
        "1" : "reading",
        "2" : "swimming",
        "3" : "listening music"
    },
    "fname" : "jeff",
    "height" : 166,
    "lname" : "jiang",
    "relationships" : [
        {
            "age" : 22,
            "fname" : "qiang",
            "lname" : "he"
        },
        {
            "age" : 22,
            "fname" : "deng",
            "lname" : "pan"
        },
        {
            "age" : 22,
            "fname" : "xiong",
            "lname" : "lan"
        }
    ]
}
一個修改內嵌數組的實例:
var newid = /.*_52848$/;var zairzrq="2016-02-15";
var zairzrq_new_Date="2016-02-15";
var i=0;//第一步,循環病例的rows,日期大於等於新入組日期的row刪除
var oldDates = db.artificial_modify.aggregate( 
[                   {$match:{"bingli":newid}}     //查詢病例匹配                   
,{$unwind : "$rows" }                   
, {$project:{                        
"_id":0                        
 ,"bingli":1                        
,riqi: "$rows.riqi"                   
 }                  
}                  
]                  
);
oldDates.forEach(function(oldDate){    
var tmpDate = oldDate.riqi;    
var bingli = oldDate.bingli;    
i++;    
if(zairzrq==tmpDate)    
{         
print(zairzrq);         
//db.artificial_modify.update({"bingli":bingli,"rows.riqi":zairzrq},{$set:{"rows.$.riqi":zairzrq_new_Date}});        
 db.artificial_modify.update({"bingli":bingli,"rows.riqi":zairzrq},{$set:{"rows.0.status.ruzu.CHUANGWH":4}});            
}});    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章