日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mongodb @aggregation 返回字段映射不上_MongoDB---基于分布式文件存储的数据库(二)...

發(fā)布時(shí)間:2025/3/20 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mongodb @aggregation 返回字段映射不上_MongoDB---基于分布式文件存储的数据库(二)... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。