溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MongoDB的使用場景和使用方法

發(fā)布時間:2020-06-05 10:54:29 來源:億速云 閱讀:518 作者:Leah 欄目:編程語言

這篇文章的知識點包括:MongoDB的簡介、MongoDB的工作原理、MongoDB的使用場景以及使用方法,閱讀完整文相信大家對MongoDB有了一定的認(rèn)識。

簡介

MongoDB 是一個基于分布式文件存儲的數(shù)據(jù)庫。由 C++ 語言編寫。旨在為 WEB 應(yīng)用提供可擴展的高性能數(shù)據(jù)存儲解決方案。

MongoDB 是一個介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的。

MongoDB最大的特點就是無Schema限制,靈活度很高。數(shù)據(jù)格式是BSON,BSON是一種類似JSON的二進(jìn)制形式的存儲格式,簡稱Binary JSON 它和JSON一樣,支持內(nèi)嵌的文檔對象和數(shù)組對象。

關(guān)系型數(shù)據(jù)庫概念對比
MongoDB的使用場景和使用方法

數(shù)據(jù)格式
MongoDB 將數(shù)據(jù)存儲為一個文檔,BSON格式。由key 和 value組成。

{     "_id" : ObjectId("5e141148473cce6a9ef349c7"),    "title" : "批量更新",     "url" : "http://cxytiandi.com/blog/detail/8",     "author" : "yinjihuan",     "tags" : [        "java",         "mongodb",         "spring"    ],     "visit_count" : NumberLong(10),     "add_time" : ISODate("2019-02-11T07:10:32.936+0000")}

使用場景

大數(shù)據(jù)量存儲場景
MongoDB自帶副本集和分片,天生就適用于大數(shù)量場景,無需開發(fā)人員通過中間件去分庫分表,非常方便。

操作日志存儲
很多時候,我們需要存儲一些操作日志,可能只需要存儲比如最近一個月的,一般的做法是定期去清理,在MongoDB中有固定集合的概念,我們在創(chuàng)建集合的時候可以指定大小,當(dāng)數(shù)據(jù)量超過大小的時候會自動移除掉老數(shù)據(jù)。

爬蟲數(shù)據(jù)存儲
爬下來的數(shù)據(jù)有網(wǎng)頁,也有Json格式的數(shù)據(jù),一般都會按照表的格式去存儲,如果我們用了MongoDB就可以將抓下來的Json數(shù)據(jù)直接存入集合中,無格式限制。

社交數(shù)據(jù)存儲
在社交場景中使用 MongoDB 存儲存儲用戶地址位置信息,通過地理位置索引實現(xiàn)附近的人,附近的地點等。

電商商品存儲
不同的商品有不同的屬性,常見的做法是抽出公共的屬性表,然后和SPU進(jìn)行關(guān)聯(lián),如果用MongoDB的話那么SPU中直接就可以內(nèi)嵌屬性。

自我陶醉
MongoDB的功能點很多,但是大部分場景下我們只用了最簡單的CRUD操作。下面隆重的介紹下MongoDB的功能點,就像你去相親一樣,不好好介紹自己的優(yōu)點又怎能讓你對面的菇?jīng)鲂膭幽兀?/p>

CRUD
CRUD也就是增刪改查,這是數(shù)據(jù)庫最基本的功能,查詢還支持全文檢索,GEO地理位置查詢等。

db.collection.insertOne()
單個文檔插入到集合中

db.collection.insertMany()
多個文檔插入到集合中

db.collection.insert()
單個或者多個文件插入到集合中

db.collection.find( )
查詢數(shù)據(jù)

db.inventory.updateOne()
更新單條

db.inventory.updateMany()
更新多條

db.inventory.deleteOne( )
刪除單條文檔

db.inventory.deleteMany()
刪除多條文檔

Aggregation
聚合操作用于數(shù)據(jù)統(tǒng)計方面,比如Mysql中會有count,sum,group by等功能,在MongoDB中相對應(yīng)的就是Aggregation聚合操作。

聚合下面有兩種方式來實現(xiàn)我們需要對數(shù)據(jù)進(jìn)行統(tǒng)計的需求,一個是aggregate,一個是MapReduce。

下圖展示了aggregate的執(zhí)行原理:
MongoDB的使用場景和使用方法

聚合內(nèi)置了很多函數(shù),使用好了這些函數(shù)我們就可以統(tǒng)計出我們想要的數(shù)據(jù)。

$project:修改輸入文檔的結(jié)構(gòu)??梢杂脕碇孛?、增加或刪除域,也可以用于創(chuàng)建計算結(jié)果以及嵌套文檔。

$match:用于過濾數(shù)據(jù),只輸出符合條件的文檔。$match使用MongoDB的標(biāo)準(zhǔn)查詢操作。

$limit:用來限制MongoDB聚合管道返回的文檔數(shù)。

$skip:在聚合管道中跳過指定數(shù)量的文檔,并返回余下的文檔。

$group:將集合中的文檔分組,可用于統(tǒng)計結(jié)果。

$sort:將輸入文檔排序后輸出。

$geoNear:輸出接近某一地理位置的有序文檔。

$unwind:將文檔中的某一個數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個值。

下圖展示了MapReduce的執(zhí)行原理:
MongoDB的使用場景和使用方法
總共4條數(shù)據(jù),query指定了查詢條件,只處理status=A的數(shù)據(jù)。

map階段對數(shù)據(jù)進(jìn)行分組聚合,也就是形成了第三部分的效果,根據(jù)cust_id去重統(tǒng)計。

reduce中的key也就是cust_id, values也就是匯總的amount集合。然后進(jìn)行sum操作,最終的結(jié)果通過out輸出到一個集合中。

Transactions
MongoDB最開始是不支持事務(wù)的,在MongoDB中,對單個文檔的操作是原子性操作。所以再設(shè)計的時候可以使用嵌入的文檔和數(shù)組來描述數(shù)據(jù)之間的關(guān)系,這樣就不用跨多個文檔和集合進(jìn)行操作,也就通過了單文檔原子性消除了許多實際用例對多文檔事務(wù)的需要。

任何事物都是有限制的,某些場景還是不能完全通過內(nèi)嵌的方式來描述數(shù)據(jù)的關(guān)系,還是會存在多個集合,對于使用MongoDB的用戶來說,如果能支持事務(wù)就很方便了。

不負(fù)眾望,MongoDB 4.0 版本的發(fā)布,為我們帶來了原生的事務(wù)操作。

Indexes
索引不用我多說了,作用大家都知道。單索引,組合索引,全文索引,Hash索引等。

db.collection.createIndex({user_id: 1, add_time: 1}, {background: true})

創(chuàng)建索引特別要注意的是將background設(shè)置為true,在建索引的過程會阻塞其它數(shù)據(jù)庫操作,background可指定以后臺方式創(chuàng)建索引,默認(rèn)為false。這可是血的教訓(xùn)呀,切記切記。

Security
MongoDB中的安全需要重視,目前啟動不知道有沒有強制的限制,以前啟動的時候可以不指定認(rèn)證的方式,也就是不需要密碼即可訪問,然后很多人都直接用的默認(rèn)端,出現(xiàn)在公網(wǎng)上,給不法分子有機可乘,出現(xiàn)了數(shù)據(jù)被刪,需要用比特幣來找回數(shù)據(jù)的案例比比皆是。

還是要開啟安全認(rèn)證,內(nèi)置了很多角色,不同的角色可操作的內(nèi)容不一樣,控制的比較細(xì)。

Replication
副本集是一組相同數(shù)據(jù)集的MongoDB實例,同時在多個節(jié)點存儲數(shù)據(jù),提高了可用性。主節(jié)點負(fù)責(zé)寫入,從節(jié)點負(fù)責(zé)讀取,提高整體性能。

副本集由下面的組件構(gòu)成:

Primary:主節(jié)點接收所有的寫操作。

Secondaries:從節(jié)點會從主節(jié)點進(jìn)行數(shù)據(jù)的復(fù)制,維護(hù)跟主節(jié)點相同的數(shù)據(jù)。用于查詢操作。

Arbiter:仲裁節(jié)點本身不存儲數(shù)據(jù),只參與選舉。
MongoDB的使用場景和使用方法

Sharding
分片是MongoDB絕對的亮點,將數(shù)據(jù)水平拆分到多個節(jié)點。MongoDB的分片是全自動的,我們只需要配置好分片的規(guī)則,它就能自動維護(hù)數(shù)據(jù)并存儲到不同節(jié)點。MongoDB使用分片來支持大數(shù)據(jù)量的存儲和高吞吐量的操作。

下圖是Mongodb的分片集群架構(gòu)圖:
MongoDB的使用場景和使用方法

MongoDB分片集群由以下組件夠成:

Shard:每個shard的數(shù)據(jù)都是獨立完整的一份。并且可以作為副本集部署。

mongos:mongos是查詢路由器,在客戶端和服務(wù)端中間的一層,請求會直接到mongos,由mongos路由到具體的Shard。

Config Servers:存儲集群所有節(jié)點、分片數(shù)據(jù)路由信息。

GridFS
GridFS是MongoDB的一個子模塊,主要用于在MongoDB中存儲文件,相當(dāng)于MongoDB內(nèi)置的一個分布式文件系統(tǒng)。

本質(zhì)上還是講文件的數(shù)據(jù)分塊存儲在集合中,默認(rèn)的文件集合分為fs.files和fs.chunks。

fs.files是存儲文件的基本信息,比如文件名,大小,上傳時間,md5等。fs.chunks是存儲文件真正數(shù)據(jù)的地方,一個文件會被分割成多個chunk塊進(jìn)行存儲,一般為256k/個。
MongoDB的使用場景和使用方法

如果你的項目中用到了MongoDB,那么你可以使用GridFS來構(gòu)建一個文件系統(tǒng),這樣就不用去購買第三方的存儲服務(wù)了。

GridFS的好處是你不用單獨去搭建一個文件系統(tǒng),直接使用Mongodb自帶的即可,備份,分片都依賴MongoDB,維護(hù)起來也方便。

知識點總結(jié)
下圖是我自己總結(jié)的一些知識點,作為一個后端開發(fā)來說,能掌握下面的內(nèi)容就已經(jīng)不錯了,畢竟我們又不是要去搶DBA的飯碗,如果大家業(yè)余時間要學(xué)習(xí)的話可以按照下面的點進(jìn)行學(xué)習(xí),幾年前我錄制了一套視頻,在我的網(wǎng)站上,大部分內(nèi)容都覆蓋到了。
MongoDB的使用場景和使用方法

工作必用
MongoDB跟Mysql的語法對比
MongoDB的使用場景和使用方法
MongoDB的使用場景和使用方法
Spring Boot中集成MongoDB
加入MongoDB的依賴:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>

配置MongoDB的信息:

spring.data.mongodb.database=testspring.data.mongodb.host=localhostspring.data.mongodb.port=27017// 用戶名,密碼省略.......

直接注入MongoTemplate就可以操作MongoDB:

@Autowiredprivate MongoTemplate mongoTemplate;

使用示列
創(chuàng)建一個實體類,對應(yīng)MongoDB的集合

@Data@Document(collection = "article_info")public class Article {    @Id    @GeneratedValue    private Long id;    @Field("title")    private String title;    @Field("url")    private String url;    @Field("author")    private String author;    @Field("tags")    private List<String> tags;    @Field("visit_count")    private Long visitCount;    @Field("add_time")    private Date addTime;}

最終存儲到數(shù)據(jù)中的格式如下:

{     "_id" : ObjectId("5e141148473cce6a9ef349c7"),    "title" : "批量更新",     "url" : "http://cxytiandi.com/blog/detail/8",     "author" : "yinjihuan",     "tags" : [        "java",         "mongodb",         "spring"    ],     "visit_count" : NumberLong(10),     "add_time" : ISODate("2019-02-11T07:10:32.936+0000")}

插入數(shù)據(jù)

Article article = new Article();article.setTitle("MongoTemplate 的基本使用 ");article.setAuthor("yinjihuan");article.setUrl("http://cxytiandi.com/blog/detail/1");article.setTags(Arrays.asList("java", "mongodb", "spring"));article.setVisitCount(0L);article.setAddTime(new Date());mongoTemplate.save(article);

數(shù)據(jù)庫語法

db.article_info.save({    "title": "批量更新",    "url": "http://cxytiandi.com/blog/detail/8",    "author": "yinjihuan",    "tags": [        "java",        "mongodb",        "spring"    ],    "visit_count": NumberLong(10),    "add_time": ISODate("2019-02-11T07:10:32.936+0000")})

更新數(shù)據(jù)

Query query = Query.query(Criteria.where("author").is("yinjihuan")); Update update = Update.update("title", "MongoTemplate")                .set("visitCount", 10); mongoTemplate.updateMulti(query, update, Article.class);

數(shù)據(jù)庫語法

db.article_info.updateMany(    {"author":"yinjihuan"},     {"$set":       {         "title":"MongoTemplate",          "visit_count": NumberLong(10)       }    })

刪除數(shù)據(jù)

Query query = Query.query(Criteria.where("author").is("yinjihuan")); mongoTemplate.remove(query, Article.class);

數(shù)據(jù)庫語法

db.article_info.remove({"author":"yinjihuan"})

查詢數(shù)據(jù)

Query query = Query.query(Criteria.where("author").is("yinjihuan")); List<Article> articles = mongoTemplate.find(query, Article.class);

數(shù)據(jù)庫語法

db.article_info.find({"author":"yinjihuan"})

存儲文件

File file = new File("/Users/yinjihuan/Downloads/logo.png");InputStream content = new FileInputStream(file);// 存儲文件的額外信息,比如用戶ID,后面要查詢某個用戶的所有文件時就可以直接查詢DBObject metadata = new BasicDBObject("userId", "1001");ObjectId fileId = gridFsTemplate.store(content, file.getName(), "image/png", metadata);

看完上述內(nèi)容,你們對MongoDB有進(jìn)一步的了解嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI