MongoDB初学者教程
1. MongoDB簡介
在本文中,我們提供了全面的MongoDB教程,該教程與基于Java的應用程序集成。 每當我們讀到NoSQL數據庫時,我們都需要知道為什么在SQL數據庫運行良好時會開發它們。 NoSQL的基礎是通過寬松的ACID (原子性,一致性,隔離性,持久性)保證而實現的,而其性能,可伸縮性,靈活性和降低的復雜性得到了支持。 大多數NoSQL數據庫在提供盡可能多的前述質量方面都走了一條路,甚至為開發人員提供了可調節的保證。
MongoDB是一個開放源代碼,面向文檔的跨平臺數據庫,它使用C ++開發,并且是最流行和使用最廣泛的NoSQL類型數據庫之一。 它可在具有鍵-值對的類JSON文檔的頂部運行,其鍵值對在每個文檔中都無法定義。 同樣,它是免費使用的,因為它是在GNU Affero通用公共許可證和Apache許可證的組合下發布的。 MongoDB將數據存儲在類似JSON的文檔(稱為BSON)中,該文檔在相同集合中的文檔之間可以具有動態模式。 可以通過簡單地添加新字段或刪除現有字段來更改同一集合中文檔的結構。
在這篇文章中,我們將研究此NoSQL數據庫的一些特性以及它在各個版本中的演變方式,并添加具有改進的可伸縮性和性能的新功能。 我們還將開發一個基于Maven的小型Java項目,其中將使用MongoDB Java驅動程序運行一些示例查詢。
2. MongoDB的發展
MongoDB由10gen開發,于2009年8月27日首次發布。MongoDB的第一個版本具有一些基本功能,授權和ACID保證,彌補了性能和靈活性方面的不足。 同樣,v1.0和v1.2的一些基本功能是:
- 基于JSON的文檔模型
- 全局鎖定在流程級別
- 駐留在RAM上的集合的索引(主要)
- 對集合中的文檔進行CRUD操作
- 主從架構中的復制支持
- Map-Reduce(在v1.2中受支持)
- Javascript函數(在v1.2中受支持)
在初始版本之后不久,MongoDB的下一版本帶來了許多新功能,并且對索引集合進行了令人興奮的改進,并且還基于先前的功能集。 為了列出演變過程,以下是MongoDB版本2中提供的一些功能:
- 分片(v1.6中支持)
- 查詢運算符(在v1.6中受支持)
- 稀疏索引和覆蓋索引(在v1.8中受支持)
- 更有效的內存使用
- 并發改進
- MapReduce改進
- 身份驗證(在v2.0中支持分片)
- 地理空間查詢和數據支持
現在,隨著大多數組織的數據庫中越來越多的數據的到來,需要提高性能,更快地建立索引和搜索文檔。 所有這些需求在MongoDB的版本3中均得到了正確回答。 以下功能是主要功能的增強,這些功能使MongoDB成為最常用的NoSQL數據庫之一:
- 聚合框架(在v2.2中受支持)
- 文字搜索(在v2.4中受支持)
- 哈希索引(在v2.4中受支持)
- 安全性增強,對數據庫的基于角色的訪問(在v2.4中受支持)
- V8 JavaScript引擎(從v2.4開始取代SpiderMonkey)
- 查詢引擎的改進(自v2.6起)
- 文件驗證(自v3.2起)
- 多個存儲引擎(自v3.2起,僅企業版)
當我們開始注意到MongoDB自開始發展以來就一直添加的功能時,我們可以很容易地看到MongoDB是一個數據庫,可以處理從啟動MVP和POC到具有數百臺服務器的企業應用程序的數據負載和更多。
3.適用于SQL開發人員的MongoDB術語
如果在SQL術語和NoSQL概念之間建立比較,我們可以更快地了解MongoDB概念。 這是Mongo與傳統MySQL系統之間的簡單類比比較:
- MySQL中的表成為MongoDB中的集合
- 行成為一個文件
- 列成為字段
- 聯接被定義為鏈接和嵌入式文檔(稍后會對此進行更多介紹)
為了消除任何誤解,這只是查看MongoDB概念的一種簡單方法,雖然每個概念可能都不能嚴格應用于其MongoDB對應對象,但這仍然很重要。
4.使用Maven制作Java項目
我們將使用許多Maven原型之一為我們的示例創建一個示例項目。 要創建項目,請在將用作工作空間的目錄中執行以下命令:
創建一個項目
mvn archetype:generate -DgroupId=com.javacodegeeks.example -DartifactId=JCG-JavaMongoDB-Example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false如果您是第一次運行maven,則完成生成命令將花費幾秒鐘,因為maven必須下載所有必需的插件和工件才能完成生成任務。 運行該項目后,我們將看到以下輸出并創建該項目:
Java MongoDB項目設置
5.添加Maven依賴項
創建項目后,請隨時在您喜歡的IDE中打開它。 下一步是向項目添加適當的Maven依賴關系。 我們將在項目中使用以下依賴項:
- mongo-java-driver :此依賴關系將Java的MongoDB驅動程序引入了我們的依賴關系。
這是pom.xml文件,其中添加了適當的依賴項:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.javacodegeeks.example</groupId><artifactId>JCG-JavaMongoDB-Example</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>JCG-JavaMongoDB-Example</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>org.mongodb</groupId><artifactId>mongo-java-driver</artifactId><version>3.4.1</version></dependency></dependencies></project>如果要檢查并使用較新版本的驅動程序,請在此處檢查發行版本。
最后,要了解添加此依賴項時添加到項目中的所有JAR,我們可以運行一個簡單的Maven命令,當我們向其添加一些依賴項時,該命令使我們能夠查看項目的完整依賴關系樹。 當我們以適當的層次結構方式添加一些自己的依賴項時,此依賴關系樹還將顯示添加了多少個依賴項。 這是我們可以使用的相同命令:
檢查依賴樹
mvn dependency:tree當我們運行此命令時,它將向我們顯示以下依賴關系樹:
檢查依賴樹
顯然,這是一個非常簡單的項目,因為它僅添加了一個Maven依賴項。
6.項目結構
在繼續進行并開始為該項目編寫代碼之前,讓我們介紹一下一旦完成將所有代碼添加到項目中之后將擁有的項目結構,以便我們知道將在該項目中放置類的位置:
項目結構
我們在此應用程序中使用了單個類,因為它可以滿足我們的所有目的。 我們可以根據需要執行的操作以及項目擴展到更復雜的操作時將該類分為多個類。
7.在Java中使用MongoDB
現在,我們可以在剛剛完成的Java項目中開始使用MongoDB查詢。 我們將從基本的CRUD操作開始,然后是分頁實現和更多查詢。 在繼續執行代碼示例之前,請確保在您的計算機上安裝并運行MongoDB 。
7.1與MongoDB建立連接
在任何應用程序中使用數據庫的第一步是連接到數據庫。 我們可以通過以下方式通過對authentication-database (默認為admin )進行身份驗證來連接到MongoDB:
MongoApp.java
System.out.println("Connecting to DB..."); List<MongoCredential> credentialsList = new ArrayList<>(); //Use username, authtication database and password in MongoCredential object MongoCredential creds = MongoCredential.createCredential("db_user", "admin", "db_password".toCharArray()); credentialsList.add(creds); ServerAddress serverAddress = new ServerAddress("localhost", 27017); //host and port MongoClient mongoClient = new MongoClient(serverAddress, credentialsList); System.out.println("Connected to MongoDB...");當我們連接到經過身份驗證的數據庫時,可以使用上面的代碼,該數據庫是安全的并且已啟用身份驗證。 如果尚未保護MongoDB安裝,則可以簡單地使用:
MongoApp.java
MongoClient mongoClient = new MongoClient("localhost", 27017);現在,我們準備使用此MongoClient對象運行各種命令,該對象已在其中建立并存儲了數據庫連接。
7.2顯示現有數據庫
我們將首先顯示系統中存在的所有數據庫,當前用戶可以訪問這些數據庫(如果安裝通過身份驗證進行保護)。 要在Mongo Shell中執行此操作,我們可以運行以下簡單命令:
使用Mongo Shell顯示數據庫
show databases;下列Java代碼段也可以執行相同的操作:
使用Java顯示數據庫
// print existing databases mongoClient.getDatabaseNames().forEach(System.out::println);這將顯示系統中的現有數據庫:
輸出量
admin local在上面的輸出中, local是默認的Mongo數據庫。
7.3創建一個集合
我們可以通過以下Java代碼片段在數據庫中創建一個集合:
MongoApp.java
// get database MongoDatabase jcgDatabase = mongoClient.getDatabase("JavaCodeGeeks");// create collection jcgDatabase.createCollection("authors"); jcgDatabase.createCollection("posts");請注意, 我們從未創建過提到的數據庫 。 盡管如此,MongoDB 不會拋出任何錯誤。 它很樂觀,并且了解如果沒有數據庫,它將為您創建一個數據庫。 如果再次運行show database命令,這次我們將看到不同的輸出:
資料庫
JavaCodeGeeks admin local數據庫是自動創建的。
7.4保存–插入收藏夾
在MongoDB中,插入的工作方式與其他數據庫略有不同。 插入時,如果數據庫中存在一個ID,它將更新同一文檔,否則,將執行插入操作。 如果我們嘗試保存數據庫中不存在的新作者,則會發生插入:
插入
MongoCollection<Document> authorCollection = jcgDatabase.getCollection("authors"); Document document = new Document(); document.put("name", "Shubham"); document.put("company", "JCG"); document.put("post_count", 20); authorCollection.insertOne(document); System.out.println("Inserted document = " + document);當運行此代碼片段時,我們將看到一個_id自動分配給該對象,以后我們可以在代碼中更新同一文檔:
輸出量
Inserted document = Document{{name=Shubham, company=JCG, post_count=20, _id=5b77c15cf0406c64b6c9dae4}}7.5保存–更新現有文檔
現在,我們已經在MongoDB的數據庫中的現有集合中插入了文檔,我們也可以更新它,因為我們知道它的ID。 我們將使用以下代碼段執行更新操作,并更新作者的姓名:
更新文件
//Find existing document Document updateQuery = new Document(); updateQuery.put("name", "Shubham");//Field to update Document newNameDocument = new Document(); newNameDocument.put("name", "Shubham Aggarwal");//Perform set operation Document updateObject = new Document(); updateObject.put("$set", newNameDocument);UpdateResult updateResult = authorCollection.updateOne(updateQuery, updateObject); System.out.println("Documents updated: " + updateResult.getModifiedCount());運行此代碼段時,我們將看到至少一個文檔已在數據庫中正確修改:
輸出量
Documents updated: 1正如我們注意到的那樣,在此提供的代碼段中,保存遵循更新約定,因為我們使用了具有給定_id的對象。
7.6獲取集合中的所有文檔
很容易找到集合中存在的所有文檔,我們只需要為其提供一個查詢對象,就可以在從集合中獲取文檔之前對其進行過濾。 讓我們看看如何使用Java代碼片段來完成此任務:
獲取所有文件
Document searchQuery = new Document(); searchQuery.put("company", "JCG");FindIterable<Document> documents = authorCollection.find(searchQuery);for (Document document: documents) {System.out.println(document); }運行上面的代碼后,我們將獲得以下輸出:
輸出量
Document{{_id=5b77c15cf0406c64b6c9dae4, name=Shubham Aggarwal, company=JCG, post_count=20}}可以對FindIterable對象執行的操作還有很多,其中一些將在以后的部分中介紹。
7.7刪除文件
刪除文檔很容易。 我們只需要提供過濾器查詢即可完成工作。
pom.xml
Document deleteSearchQuery = new Document(); deleteSearchQuery.put("_id", new ObjectId("5b77c15cf0406c64b6c9dae4")); DeleteResult deleteResult = authorCollection.deleteOne(deleteSearchQuery); System.out.println("Documents updated: " + deleteResult.getDeletedCount());運行上面的代碼后,我們將獲得以下輸出:
輸出量
Documents updated: 1請注意,我們將ID的值不是用作String而是用作ObjectId因為MongoDB可以理解。 盡管完全可以使用簡單的String作為ID,但是標識字段不支持其他類型。 最后,請注意,我們使用了deleteOne方法,該方法僅刪除單個文檔。 即使MongoDB為提供的過濾器找到了多個文檔(在ID的情況下,找不到多個文檔,但在其他情況下可能找到多個文檔),它仍將僅從其中刪除一個文檔(刪除了第一個匹配的文檔)。 要刪除所有過濾的文檔,我們可以使用deleteMany方法。
8.解碼的_id字段
每個MongoDB文檔都有一個_id字段,它是集合中給定文檔的唯一標識符。 看起來像:
_ID
{"_id" : ObjectId("5b77c15cf0406c64b6c9dae4")... other fields ... }很多時候,人們(絕對不是開發人員)認為這是隨機生成的String令牌,它是經過精心選擇的,因此在此collection中保存的所有數字文檔中都保持唯一。 但這種情況并非如此。 MongoDB中所有文檔的每個_id是一個12字節的十六進制數字,可確保文檔在集合中的唯一性。 如果開發人員自己未提供,則由MongoDB生成(在這種情況下,該String的含義將完全改變,但仍保留在集合中的唯一標識符)。
在這12個字節中,前4個字節描述了當前時間戳,接下來的3個字節描述了機器標識符,接下來的2個字節描述了該機器上MongoDB服務器的進程ID,最后3個字節是簡單的自動遞增計數器由MongoDB服務器維護。 這也可以用一個簡單的圖來解釋:
_id字段已解碼
此字段還表示MongoDB集合中每個文檔的主鍵。
9. MongoDB的局限性
盡管MongoDB可以擴展很多并且具有超快速的索引,但是它也有一些可能的缺點。 我們使用“可能”一詞,因為這可能會對您的用例造成不利影響,也可能不會造成不利影響。 讓我們在這里看到一些缺點:
- 每個文件可以占用的最大大小為16MB。
- MongoDB文檔中的最大文檔嵌套級別為100
- 數據庫名稱限制為64個字符
- 如果我們在任何字段上應用索引,則該字段值不能包含超過1024個字節
- 哈希索引不能唯一
- 如果數據超過300 MB,則無法自動回滾。 在這種情況下,需要人工干預
正如我們所提到的,這些是一些缺點,這些缺點在您的應用程序中可能永遠不會發生,并且您無需為此做任何事情。
10. MongoDB和RDBMS
MongoDB和RDBMS數據庫之戰永無止境。 開發人員一直在爭論哪一個比另一個要快或更好,但是答案是,由于使用每種情況的用例,兩者之間沒有比較。 值得一提的是,讓我們在這里描述MongoDB相對于RDBS數據庫的優勢:
- MongoDB數據庫中的集合是無模式的 。 插入集合中的文檔可以具有不同的字段集,而不必在應用程序級別或數據庫級別執行任何其他操作。
- MongoDB具有豐富的查詢支持。 MongoDB支持對數據庫的動態查詢。
- 數據庫對象和應用程序對象之間的轉換或映射很簡單,因為大多數應用程序都支持使用數據庫對象進行JSON映射。
- 集成的內存支持使用戶可以以更快的方式訪問數據。
MongoDB并不是神奇的更快。 如果您以相同的方式存儲相同的數據,并以完全相同的方式對其進行訪問,那么您真的不應該期望結果會大相徑庭。 畢竟,MySQL和MongoDB都是GPL,因此,如果Mongo中包含一些神奇的更好的IO代碼,則MySQL團隊可以將其合并到他們的代碼庫中。
人們看到了真實的MongoDB性能,主要是因為MongoDB允許您以對工作負載更敏感的另一種方式進行查詢。 例如,考慮一種設計,該設計以規范化方式保留了有關復雜實體的許多信息。 這可以輕松地使用MySQL(或任何關系數據庫)中的數十個表以正常形式存儲數據,并需要許多索引來確保表之間的關系完整性。
現在考慮與文檔存儲相同的設計。 如果所有這些相關表都從屬于主表(并且經常屬于主表),那么您也許可以對數據建模,以便將整個實體存儲在單個文檔中。 在MongoDB中,我們可以將其作為單個文檔存儲在單個集合中。 這是MongoDB開始提供卓越性能的地方。
11.結論
在本課程中,我們Swift熟悉了在基于maven的簡單Java應用程序中使用MongoDB的過程,并使用更新的API對我們的集合執行了CRUD操作。
我們還研究了MongoDB的各種優勢。 盡管您可能希望在許多用例上通過SQL數據庫使用MongoDB,但我認為Schema靈活性最有可能是影響此決策的最重要因素 。 MongoDB使我們能夠將數據或文檔存儲在可以具有不同字段的集合中,這可以在應用程序的開發階段提供很大幫助,而且還可以從可能具有或不具有相同屬性和架構的多個源中提取數據與他們相關聯。 與必須預先定義列并且可以懲罰具有稀疏數據的RDBMS數據庫相比,在MongoDB中,這是一種規范,并且是大多數用例共享的功能。 能夠將屬性深層嵌套到文檔中,將值的數組添加到屬性中,并且始終能夠搜索和索引這些字段,這有助于應用程序開發人員利用MongoDB的無模式本質。
最后,擴展和分片是MongoDB用例的最常見模式。 使用內置分片和副本集輕松進行數據復制,以及從讀取負載中卸載主要服務器,可以幫助開發人員有效地存儲數據。 除了MongoDB提供的優勢之外,MongoDB仍然有一些批評者提到規模并不是我們在每個應用程序中都需要的東西,因此消除了偏愛MongoDB的最重要因素之一。
12.下載源代碼
這是帶有Java編程語言的MongoDB教程。
下載您可以在此處下載此示例的完整源代碼: MongoDB示例
翻譯自: https://www.javacodegeeks.com/2018/08/mongodb-tutorial-for-beginners.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的MongoDB初学者教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux文件统计命令(linux文件统
- 下一篇: ddos攻击防御的区别与联系(ddos攻