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