mongodb @aggregation 返回字段映射不上_MongoDB---基于分布式文件存储的数据库(二)...
MongoDB基礎入門到高級進階視頻教程
【MongoDB】
六、Document 操作
在MongoDB中文檔是指多個鍵及其關聯的值有序地放置在一起就是文檔,其實指的就是數據,也是我們平時操作最多的部分。
MongoDB中的文檔的數據結構和 JSON 基本一樣。所有存儲在集合中的數據都是 BSON 格式。
BSON 是一種類似 JSON 的二進制形式的存儲格式,是 Binary JSON 的簡稱。
1. 新增文檔
1.1 新增單一文檔
1.1.1 insert函數
語法格式為:db.COLLECTION_NAME.insert(document)。
向test集合中插入單個文檔。
db.test.insert({title:'北京尚學堂',description:'程序員的搖籃',url:'www.bjsxt.com',tags:['java','大數據','python'],'time':new ISODate('2020-01-01T10:10:10.000Z')})
1.1.2 save函數
向test集合中插入單個文檔。
db.test.save({title:'百戰程序員',description:'身經百戰,高薪相伴',url:'www.itbaizhan.cn',tags:['javaWeb實戰','數據庫實戰','微服務實戰']})
1.1.3 insertOne函數
在MongoDB3.2以后的版本中,提供了insertOne()函數用于插入文檔。
向test集合中插入單個文檔。
db.test.insertOne({title:'尚學堂大數據',description:'培養大數據人才的搖籃',url:'www.bjsxt.com',tags:['hadoop','spark','Hbase']})
1.2 批量新增文檔
1.2.1 insert函數
向test集合中批量插入多個文檔
db.test.insert([{title:'java',tags:['JavaSE','JavaEE','JavaME']},{title:'ORM',tags:['Mybatis','Hibernate']},{title:'Spring',tags:['SpringMVC','SpringBoot','SpringCloud']}])
1.2.2 save函數
向test集合中批量插入多個文檔
db.test.save([{title:'java',tags:['JavaSE','JavaEE','JavaME']},{title:'ORM',tags:['Mybatis','Hibernate']},{title:'Spring',tags:['SpringMVC','SpringBoot','SpringCloud']}])
1.2.3 insertMany函數
在MongoDB3.2以后的版本中,提供了insertMany函數用于插入文檔。
語法格式:db.COLLECTION_NAME.insertMany([{},{},{},.....])
向test集合中批量插入多個文檔
db.test.insertMany([{title:'java',tags:['JavaSE','JavaEE','JavaME']},{title:'ORM',tags:['Mybatis','Hibernate']},{title:'Spring',tags:['SpringMVC','SpringBoot','SpringCloud']}])
1.3 通過變量新增文檔
Mongo Shell工具允許我們定義變量。所有的變量類型為var類型。也可忽略變量類型。變量中賦值符號后側需要使用小括號來表示變量中的值。我們可以將變量作為任意插入文檔的函數的參數。
語法格式:變量名=(<變量值>)
1.3.1 變量新增單一文檔
定義變量
document=({title:'SpringCloud',tags:['Spring Cloud Netflix','Spring Cloud Security','Spring Cloud Consul']})
新增文檔
db.test.insert(document);
db.test.save(document);
db.test.insertOne(document);
1.3.2 變量批量新增文檔
定義變量
document=([{title:'SpringCloud',tags:['Spring Cloud Netflix','Spring Cloud Security','Spring Cloud Consul']},{title:'SpringBoot',tags:['Spring Boot']}])
新增文檔
db.test.insert(document);
db.test.save(document);
db.test.insertMany(document);
2 查詢文檔
MongoDB是通過findOne()和find()函數來實現文檔查詢的。
2.1 基礎應用
2.1.1 findOne函數
findOne函數用于查詢集合中的一個文檔。語法如下:
db.集合名稱.findOne({<query>},
{<projection>
});
參數解釋:
- query:可選,代表查詢條件。
- projection:可選,代表查詢結果的投影字段名。即查詢結果需要返回哪些字段或不需要返回哪些字段。
查詢stu集合中第一個文檔:
db.stu.findOne();
或
db.stu.findOne({});
查詢stu集合中name字段為lisi的第一個文檔:
db.stu.findOne({'name':'lisi'});
查詢stu集合中第一個文檔,且只顯示name字段:
db.stu.findOne({},{'name':1});
查詢stu集合中第一個文檔,且不顯示name和age字段:
db.stu.findOne({},{'name':0,'age':0});
注意:在projection中不能使用{'name':0, 'age':1}這種語法格式,這是錯誤的語法。projection只能定義要返回的字段或不返回的字段。_id字段是MongoDB維護的字段,是唯一可以在projection中獨立使用的。如:{_id:0, 'name':1, 'age':1}
2.1.2 find函數
find函數用于查詢集合中的若干文檔。語法如下:
db.stu.find({<query>},{<projection>});
參數解釋:
query:可選,代表查詢條件。
projection:可選,代表查詢結果的投影字段名。即查詢結果需要返回哪些字段或不需要返回哪些字段。
查詢stu集合中的所有文檔:
db.stu.find()
或
db.stu.find({})
查詢stu集合中所有name字段為lisi的文檔:
db.stu.find({'name':'lisi'});
2.1.3 投影約束
在MongoDB中,_id字段是默認返回顯示的投影字段。
查詢stu集合中所有文檔,且只顯示name字段:
db.stu.find({},{'name':1});
查詢stu集合中所有文檔,且顯示除name字段以外的其他字段:
db.stu.find({},{'name':0});
非_id字段,在投影約束中不能互斥,否則拋出異常。如:{"name":1, "age":0}拋出異常。
包含_id字段,在投影約束中可以和其他字段互斥約束,但是,_id字段必須為非投影顯示約束(0),
如:{"name":1, "_id":0} 正確的。
包含_id字段,在投影約束中,如果和其他字段投影約束互斥,且_id字段投影約束為顯示(1),會拋出異常,
如:{"_id":1, "name":0} 拋出異常。
常用方式: {"_id":0, "xxx":1} {"xxx":0}
總結:投影時,_id為1的時候,其他字段必須是1;_id是0的時候,其他字段可以是0;如果沒有_id字段約束,多個其他字段必須同為0或同為1。
2.2 pretty函數
pretty函數用于格式化find函數查詢結果。讓查詢結果更易查看。findOne函數自動附帶格式化查詢結果的能力。
語法:
db.stu.find().pretty();
2.3 單條件邏輯運算符
如果你熟悉常規的 SQL 數據,通過下表可以更好的理解 MongoDB 的條件語句查詢:
在MongoDB中字符串也可以比較大小。按照Unicode編碼順序比較大小。
日期可以比較大小: 過往 < 現在 < 未來。
2.4 多條件邏輯運算符
2.4.1 And條件
MongoDB 的 find() 和 findOne() 函數可以傳入多個鍵(key),每個鍵(key)以逗號隔開,即常規 SQL 的 AND 條件。
查詢stu集合中name字段為lisi,且age字段大于20的文檔:
db.stu.find({'name':'lisi', 'age':{'$gt':20}});
2.4.2 Or條件
MongoDB OR 條件語句使用了關鍵字 $or,語法格式如下:
db.集合名稱.find({
$or: [
{key1: value1}, {key2:value2}
]
}
)
查詢stu集合中name字段為lisi或age字段大于22的文檔:
db.stu.find({'$or':[{'name':'lisi'},{'age':{'$gt':22}}]});
2.4.3 And和Or的配合使用
查詢集合stu中name字段為zhangsan,或name字段為lisi且age字段為22的文檔。
db.stu.find({$or:[{'name': 'zhangsan'},{'name':'lisi', 'age':22}]});
2.5 $type查詢
在MongoDB中根據字段的數量類型來查詢數據使用$type操作符來實現,具體使用法語:
db.集合名.find({屬性名:{$type:類型值}}) //這里的類型值能使用Number也能使用alias
$type的有效值如下:
查詢stu集合中name字段類型為字符串的文檔:
db.stu.find({'name':{$type:2}});
或
db.stu.find({'name':{$type:'string'}});
2.6 正則查詢
MongoDB中查詢條件也可以使用正則表達式作為匹配約束。
語法:
db.集合名稱.find({字段名:正則表達式});
或
db.集合名稱.find({字段名:{$regex:正則表達式[, $options:正則選項]}});
正則表達式格式:/xxx/
正則選項:
- i - 不區分大小寫以匹配大小寫的情況。
- m - 對于包含錨點的模式(即^對于開始, $對于結尾),在每行的開頭或結尾處匹配具有多行值的字符串(可解析單字段中的換行符n)。如果沒有此選項,這些錨點將在字符串的開頭或結尾處匹配。
- x - 設置x選項后,正則表達式中的非轉義的空白字符將被忽略。需要$regex與$options語法
- s - 允許點字符(即.)匹配包括換行符在內的所有字符。需要$regex與$options語法
i,m,x,s可以組合使用。
查詢stu集合中name字段以'z'開頭的數據
db.stu.find({'name':/^z/});
或
db.stu.find({'name':{$regex:/^z/}});
查詢stu集合中name字段以'n'結尾的數據
db.stu.find({'name':/n$/});
或
db.stu.find({'name':{$regex:/n$/}});
查詢stu集合中name字段中包含'a'的數據
db.stu.find({'name':/a/});
或
db.stu.find({'name':{$regex:/a/}});
查詢stu集合中name字段以'L'開頭的數據,且忽略大小寫
db.stu.find({'name':/^L/i});
或
db.stu.find({'name':{$regex:/^L/i}});
或
db.stu.find({'name':{$regex:/^L/, $options:'i'}});
查詢stu集合中remark字段以'A'開頭的數據,且忽略大小寫,同時增加錨點
db.stu.find({'name':/^L/im});
或
db.stu.find({'name':{$regex:/^L/im}});
或
db.stu.find({'name':{$regex:/^L/, $options:'im'}});
查詢stu集合中name字段已'z'開頭、'n'結尾的數據
db.stu.find({'name':/^z.*n$/});
或
db.stu.find({'name':{$regex:/^z.*n$/}});
查詢stu集合中name字段以'z'或'l'開頭的數據
db.stu.find({'name':{$in:[/^z/, /^l/]}});
查詢stu集合中name字段不以'z'開頭的數據
db.stu.find({'name':{$not:/^z/}});
查詢stu集合中name字段不以'z'或'l'開頭的數據
db.stu.find({'name':{$nin:[/^z/, /^l/]}});
2.7 分頁查詢
在MongoDB中,使用函數limit()和skip()來實現分頁數據查詢。
2.7.1 limit函數
在MongoDB中讀取指定數量的數據記錄,可以使用MongoDB的Limit方法,limit()方法接受一個數字參數,該參數指定從MongoDB中讀取的記錄條數。
語法:
db.集合名稱.find().limit(查詢數量);
查詢stu集合中的前10條數據:
db.stu.find().limit(10);
不使用limit函數,默認查詢集合中全部文檔。如果limit函數不傳遞參數,也是查詢集合中的全部文檔。
2.7.2 skip函數
在MongoDB中使用skip()方法來跳過指定數量的文檔,skip方法同樣接受一個數字參數作為跳過的文檔條數。
語法:
db.集合名稱.find().[limit(查詢數量).]skip(跳過數量);
查詢stu集合第二條到最后一條的文檔:
db.stu.find().skip(1);
或
db.stu.find().limit().skip(1);
假設每頁查詢文檔數為2,現查詢stu集合中第二頁文檔:
db.stu.find().limit(2).skip(2);
不使用skip函數,不會跳過任何文檔,從集合的第一條文檔開始查詢。如果skip函數不傳遞參數,也是不跳過任何文檔。
2.8 排序
在 MongoDB 中使用 sort() 方法對數據進行排序,sort() 方法可以通過參數指定排序的字段,并使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而 -1 是用于降序排列。
語法:
db.集合名稱.find().sort({key1:sortType1, key2:sortType2});
查詢stu集合中全部文檔,以age字段升序排列:
db.stu.find().sort({'age':1});
查詢stu集合中全部文檔,以age字段升序排列,如果age相同,則以name字段降序排列:
db.stu.find().sort({'age':1, 'name':-1});
3. 更新文檔
MongoDB通過update函數與save函數來更新集合中的文檔。
3.1 save更新文檔
save()函數的作用是保存文檔,如果文檔存在則覆蓋,如果文檔不存在則新增。save()函數對文檔是否存在的唯一判斷標準是"_id"系統唯一字段是否匹配。所以使用save()函數實現更新操作,則必須提供"_id"字段數據。
save()函數的語法是:
db.集合名稱.save(
<document>
);
參數document代表要修改的文檔內容,要求必須提供"_id"字段數據。
使用save()函數實現更新操作:
db.test.save(
{
"_id" : ObjectId("5d0207e460ad10791be757d2"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個 Nosql 數據庫",
"by" : "北京尚學堂",
"tags" : [
"mongodb",
"NoSQL"
],
"likes" : 100
}
)
3.2 update更新文檔
update() 函數用于更新已存在的文檔。
語法格式:
db.集合名稱.update(
<query>,
<update>,
< upsert:boolean>,
< multi:boolean>
)
參數說明:
query : update的查詢條件,類似sql update更新語法內where后面的內容。
update : update的對象和一些更新的操作符等,也可以理解為sql update查詢內set后面的。
upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入這個document,true為插入,默認是false,不插入。
multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新。只有在表達式更新語法中才可使用。
在MongoDB中的update是有兩種更新方式,一種是覆蓋更新,一種是表達式更新。
覆蓋更新:顧名思義,就是通過某條件,將新文檔覆蓋原有文檔。
表達式更新:這種更新方式是通過表達式來實現復雜更新操作,如:字段更新、數值計算、數組操作、字段名修改等。
3.2.1 覆蓋更新
通過update方法來更新一個完整的文檔:
db.col.update({"title" : "MongoDB 教程"},
{
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個 Nosql 數據庫",
"by" : "北京尚學堂",
"likes" : 100
}
)
3.2.2 表達式更新
語法:
db.集合名稱.update(<query>,
<doc_projection>,
<upsert>,
<multi>
);
doc_projection語法:
{$表達式:{具體更新規則}
}
① $inc
- 用法:{$inc:{field:value}}
- 作用:對一個數字字段的某個field增加value
- 示例:將name為zhangsan的學生的age增加5
- 命令:db.stu.update({name:"zhangsan"},{$inc:{age:5}})
② $set
- 用法:{$set:{field:value}}
- 作用:把文檔中某個字段field的值設為value,如果field不存在,則增加新的字段并賦值為value。
- 示例:把zhangsan的年齡設為23歲
- 命令:db.stu.update({name:"zhangsan"},{$set:{'age':23}})
③ $unset
- 用法:{$unset:{field:1}}
- 作用:刪除某個字段field
- 示例:將zhangsan的年齡字段刪除
- 命令:db.stu.update({name:"zhangsan"},{$unset:{age:1}})
④ $push
- 用法:{$push:{field:value}}
- 作用:把value追加到field里。注:field只能是數組類型,如果field不存在,會自動插入一個數組類型
- 示例:給zhangsan添加別名"xiaozhang"
- 命令:db.stu.update({name:"zhangsan"},{$push:{"alias":"xiaozhang"}})
⑤ $addToSet
- 用法:{$addToSet:{field:value}}
- 作用:加一個值到數組內,而且只有當這個值在數組中不存在時才增加。
- 示例:往zhangsan的別名字段里添加兩個別名A1、A2
- 命令:db.stu.update({name:"zhangsan"},{$addToSet:{"alias":["A1","A2"]}})
注意:此處加入的數據是一個數據為A1和A2的數組對象。并不是將兩個數據依次加入alias數組中。
⑥ $pop
- 用法:刪除數組內第一個值:{$pop:{field:-1}}、刪除數組內最后一個值:{$pop:{field:1}}
- 作用:用于刪除數組內的一個值
- 示例:刪除zhangsan記錄中alias字段中最后一個別名
- 命令:db.stu.update({name:"zhangsan"},{$pop:{"alias":1}})
⑦ $pull
- 用法:{$pull:{field:_value}}
- 作用:從數組field內刪除所有等于_value的值
- 示例:刪除zhangsan記錄中的別名xiaozhang
- 命令:db.stu.update({name:"zhangsan"},{$pull:{"alias":"xiaozhang"}})
⑧ $pullAll
- 用法:{$pullAll:value_array}
- 作用:用法同$pull一樣,可以一次性刪除數組內的多個值。
- 示例:刪除zhangsan記錄內的A1和A2別名
- 命令:db.stu.update({name:"zhangsan"},{$pullAll:{"alias":["A1","A2"]}})
⑨ $rename
- 用法:{$rename:{old_field_name:new_field_name}}
- 作用:對字段進行重命名。底層實現是先刪除old_field字段,再創建new_field字段。
- 示例:把zhangsan記錄的name字段重命名為sname
- 命令:db.stu.update({name:"zhangsan"},{$rename:{"name":"sname"}})
⑩ 更多案例
- 只更新第一條滿足條件的記錄:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
- 更新全部滿足條件的記錄:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
- 如果沒有符合條件的數據,則添加一條:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
- 如果沒有符合條件的數據,則全部添加進去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
- 只更新第一條記錄:(等同第一個)
db.col.update( { "count" : { $lt : 10 } } , { $set : { "count" : 1} },false,false );
4. 刪除文檔
MongoDB是通過remove()函數、deleteOne()函數、deleteMany()函數來刪除集合中的文檔。
4.1 remove函數
語法格式是:
db.集合名稱.remove(<query>,
<justOne:boolean>
);
參數說明:
- query:要刪除的文檔條件,相當于SQL語法中的where子句作用。
- justOne:可選參數,布爾類型,代表是否只刪除第一個匹配條件滿足的文檔。默認值為false,代表刪除全部滿足匹配條件的文檔。
注意:此方法已經過時,官方推薦使用deleteOne()和deleteMany()函數來實現刪除操作。且在4.0-版本中,remove()函數并不會真正的釋放存儲空間,需要使用db.repairDatabase()函數來釋放存儲空間。在4.2.1版本中,刪除函數repairDatabase()。
4.1.1 刪除全部
刪除stus集合中的全部文檔:
db.stus.remove({});
4.1.2 條件刪除
- 刪除stus集合中age字段為10的文檔。
db.stus.remove({'age':10});
- 刪除stus集合中age字段大于20的第一個文檔。
db.stus.remove({'age':{'$gt':20}}, true);
- 刪除stus集合中age字段小于50的全部文檔。
db.stus.remove({'age':{'$lt':50}});
或
db.stus.remove({'age':{'$lt':50}}, false);
4.2 deleteOne函數
語法格式:
db.集合名稱.deleteOne({<query>});參數解釋:
query:要刪除的文檔條件,相當于SQL語法中的where子句作用。
刪除stus集合中name字段為zhangsan的第一個文檔:
db.stus.deleteOne({'name':'zhangsan'});
4.3 deleteMany函數
語法格式:
db.集合名稱.deleteMany({<query>});參數解釋:
query:要刪除的文檔條件,相當于SQL語法中的where子句作用。
刪除stus集合中age字段大于10的所有文檔:
db.stus.deleteMany({'age':{'$gt':10}});
總結
以上是生活随笔為你收集整理的mongodb @aggregation 返回字段映射不上_MongoDB---基于分布式文件存储的数据库(二)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python聚类分析sklearn_如何
- 下一篇: python分形几何_使用 Python