Mongo入門

什麼是MongoDBhtml

MySQLjava

memory 內存引擎數據庫

NoSQL最大的特色: 默認支持分佈式(內置分佈式解決方案) 高性能,高可用性和可伸縮性數組

在NoSQL界, MongoDB是一個最像關係型數據庫的非關係型數據庫緩存

MongoDB應用場景 適用範圍 1)網站實時數據: 例如:日誌、Timeline、用戶行爲(代替方案:用日誌) 2)數據緩存:緩存的數據,它必定是臨時的 (關係型數據有一份已經持久化) 3)大尺寸、低價值數據存儲: 搜索引擎的圖片文件、視頻文件(結構化), 一份存磁盤、一份存Mongo 4)高伸縮性場景:機器能夠任意的增減 5)對象或JSON數據存儲: 徹底能夠選擇用Redisbash

不適用範圍 1)高度事務性系統: 例如:金融系統的核心數據 高機密的用戶數據(只能選擇傳統關係型數據庫)服務器

2)傳統的商業智能應用:結構化查詢要求很是高,常常作關聯查詢統計 (若是都是單表查詢,用Java程序來實現關聯) Map,List (id_az_a)app

MongoDB 4.0 支持事務操做(分佈式事務的一種解決方案)分佈式

java簡單操做mongoDB 2.鏈接Mongo 2.1.無用戶名密碼驗證ide

//鏈接"localhost:27017"能夠直接使用無參構造new MongoClient();
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
複製代碼

2.2.須要用戶名密碼驗證

//鏈接到MongoDB服務 若是是遠程鏈接能夠替換「localhost」爲服務器所在IP地址  
//ServerAddress()兩個參數分別爲 服務器地址 和 端口  
    ServerAddress serverAddress = new ServerAddress("localhost",27017);  
    List<ServerAddress> addrs = new ArrayList<ServerAddress>();  
    addrs.add(serverAddress);  
//MongoCredential.createScramSha1Credential()三個參數分別爲 用戶名 數據庫名稱 密碼  
   MongoCredential credential = MongoCredential.createScramSha1Credential("username",   "databaseName", "password".toCharArray());  
   List<MongoCredential> credentials = new ArrayList<MongoCredential>();  
   credentials.add(credential);  

複製代碼

//經過鏈接認證獲取MongoDB鏈接

MongoClient mongoClient = new MongoClient(addrs,credentials);
複製代碼

3.獲取操做數據庫/不存在會建立

MongoDatabase db = mongoClient.getDatabase("mydb");
複製代碼

4.建立集合 Mongo中的集合,能夠看作是數據庫中的表。

db.createCollection("user");
複製代碼

5.得到指定集合,並遍歷全部數據

MongoCollection<Document> users = db.getCollection("user");
FindIterable<Document> documents = users.find();
for (Document document : documents) {
    System.out.println(document);
}
複製代碼

6.查詢 6.1 經過Document查詢條件 //查找全部name = csc的document

Document query1 = new Document("name", "csc");
FindIterable<Document> documents = users.find(query1);
for (Document d : documents) {
    System.out.println(d.toJson());
}
使用運算符「$lt」,"$gt","$lte","$gte"
//age < 25
Document query2 = new Document("age", new Document("$lt", 25));
FindIterable<Document> documents = users.find(query2);
      
and鏈接多個條件

Document query3 = new Document("age", new Document("$lt", 25)).append("name", "csc");
FindIterable<Document> documents = users.find(query3);  
也能夠:
Document query4 = new Document("name", "csc");
query4.put("age", new Document("$lt", 25));
FindIterable<Document> documents = users.find(query4);
       
or鏈接多個條件

//name = csc || name == dqr
Document query5 = new Document("$or", Arrays.asList(new Document("name", "csc"), new Document("name", "dqr")));
FindIterable<Document> documents = users.find(query5);
       
between...and...

//若是這樣寫,會值返回age > 20的document,由於後面一個key爲"age"的把前面一個覆蓋了。
Document query6 = new Document("age", new Document("$lt", 23)).append("age", new Document("$gt", 20));
FindIterable<Document> documents = users.find(query6);
//正確寫法:
Document query6 = new Document("age", new Document("$lt", 23).append("$gt", 20));
FindIterable<Document> documents = user.find(query6);     
複製代碼

6.2 經過Filters指定查詢條件(更簡潔的作法) 相等:eq

FindIterable<Document> documents = user.find(Filters.eq("name", "csc"));
複製代碼

不等:ne、lt、lte、gt、gte

FindIterable<Document> documents = user.find(Filters.lte("age", 23));
複製代碼

in:

FindIterable<Document> documents = user.find(Filters.in("age", Arrays.asList(23,25,27)));
複製代碼

and:

Bson and = Filters.and(Filters.eq("name", "csc"), Filters.ne("age", 25));
FindIterable<Document> documents = user.find(and);
複製代碼

or:

FindIterable<Document> documents = user.find(Filters.or(Filters.eq("age",23),Filters.eq("age", 25)));         
複製代碼

6.3 count l

ong cnt = user.count(Filters.eq("age", 27));
System.out.println(cnt);
複製代碼

6.4 sort //按name升序

FindIterable<Document> documents = user.find().sort(Sorts.ascending("name"));
//按age將序
FindIterable<Document> documents = user.find().sort(Sorts.descending("age"));
//按name升序,name相同的按age降序
FindIterable<Document> documents = user.find().sort(Sorts.orderBy(Sorts.ascending("name"), Sorts.descending("age")));
複製代碼

6.5 skipe & limit //跳過前5條(0-4),返回(5-9)共5條。

FindIterable<Document> documents = user.find().sort(Sorts.descending("age")).skip(5).limit(5);
複製代碼

6.6 distinct

DistinctIterable<String> name = user.distinct("name", String.class);
DistinctIterable<Integer> age = user.distinct("age", Integer.class);
for (Integer a : age) {
    System.out.println(a);
}
for (String s : name) {
    System.out.println(s);
}
複製代碼

7.添加document 7.1添加單個document

Document doc = new Document();
doc.put("name", "zhangsan");
doc.put("age", 40);
user.insertOne(doc);
複製代碼

7.2添加多個文檔

List<Document> docs = new LinkedList<Document>();
for(int i=0; i<10; i++){
    Document doc = new Document();
    doc.put("name", "zhangsan"+i);
    doc.put("age", 40+i);
    docs.add(doc);
}
user.insertMany(docs);
複製代碼

8.修改document updateOne/updateMany:

user.updateMany(Filters.eq("age", 25), new Document("$set", new Document("age", 16).append("name","xxx25")));
複製代碼

9.刪除document deleteOne/deleteMany:

//刪除第一個符合條件的
user.deleteOne(Filters.eq("age", 17));
//刪除全部符合條件的
user.deleteMany(Filters.eq("age", 17));
複製代碼

10.aggregate 以流水線的方式,分階段處理document。

主要階段: $project 對流入的每一個document進行投影操做,相似於select field1, field2, ... 能夠添加新字段、或刪除已存在的某些字段。

MongoClient mongo = new MongoClient();
MongoDatabase db = mongo.getDatabase("test");
MongoCollection<Document> hobby = db.getCollection("student");
hobby.insertOne(new Document("name", "csc").append("hobby", Arrays.asList("reading", "coding")));
hobby.insertOne(new Document("name", "nicky").append("hobby", Arrays.asList("game")));
hobby.insertOne(new Document("name", "jack").append("hobby", Arrays.asList("movie")));
hobby.insertOne(new Document("name", "tom").append("hobby", Arrays.asList("reading", "coding")));
hobby.insertOne(new Document("name", "lucy").append("hobby", Arrays.asList("reading", "football")));
hobby.insertOne(new Document("name", "lion").append("hobby", Arrays.asList("basketball", "football")));
AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))));
for (Document document : aggregate) {
    System.out.println(document.toJson());
} 
複製代碼

只有_id默認輸出的,不想輸出該字段,須要設置爲0,須要輸出的其餘字段須要手動設置爲1. 輸出結果:

{ "name" : "csc", "hobby" : ["reading", "coding"] }
{ "name" : "nicky", "hobby" : ["game"] }
{ "name" : "jack", "hobby" : ["movie"] }
{ "name" : "tom", "hobby" : ["reading", "coding"] }
{ "name" : "lucy", "hobby" : ["reading", "football"] }
{ "name" : "lion", "hobby" : ["basketball", "football"] } 
複製代碼

$match 相似於where字句

AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
            new Document("$project", new Document("name",1).append("_id", 0).append("hobby", 1))
            ,new Document("$match", new Document("name", "csc"))
    )); 
複製代碼

輸出結果:

{ "name" : "csc", "hobby" : ["reading", "coding"] }
複製代碼

limit &skip同上面的用法 $unwind 把數組中的元素拆分爲多個document。

AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
            new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))
            ,new Document("$unwind", "$hobby")
    ));
複製代碼

輸出結果:

{ "name" : "csc", "hobby" : "reading" }
{ "name" : "csc", "hobby" : "coding" }
{ "name" : "nicky", "hobby" : "game" }
{ "name" : "jack", "hobby" : "movie" }
{ "name" : "tom", "hobby" : "reading" }
{ "name" : "tom", "hobby" : "coding" }
{ "name" : "lucy", "hobby" : "reading" }
{ "name" : "lucy", "hobby" : "football" }
{ "name" : "lion", "hobby" : "basketball" }
{ "name" : "lion", "hobby" : "football" }
複製代碼

group
相似於group by,可使用各類聚合操做符,經常使用的有:sum, avg,max, min,first, $last //計算每一個hobby的人數

AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
            new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))
            ,new Document("$unwind", "$hobby")
            ,new Document("$group", new Document("_id", "$hobby").append("count", new Document("$sum", 1)))
    ));
複製代碼

必須首先設置("_id", "hobby"),這句的含義是group by hobby這個字段。引用字段必定要添加打頭。 如:輸出每一個hobby的第一個name: ("fisrt","name")。

AggregateIterable<Document> aggregate = hobby.aggregate(Arrays.asList(
            new Document("$project", new Document("name", 1).append("_id", 0).append("hobby", 1))
            ,new Document("$unwind", "$hobby")
            ,new Document("$group", new Document("_id", "$hobby").append("count", new Document("$sum", 1)).append("first", new Document("$first", "$name")))
    ));
複製代碼

輸出結果:

{ "_id" : "basketball", "count" : 1, "first" : "lion" }
{ "_id" : "football", "count" : 2, "first" : "lucy" }
{ "_id" : "movie", "count" : 1, "first" : "jack" }
{ "_id" : "game", "count" : 1, "first" : "nicky" }
{ "_id" : "coding", "count" : 2, "first" : "csc" }
{ "_id" : "reading", "count" : 3, "first" : "csc" }
複製代碼

11.mapreduce map function

function() {
   ...//自定義操做
   emit(key, value);
}
複製代碼

文檔中的說明:

In the map function, reference the current document as this within the function.
The map function should not access the database for any reason.
The map function should be pure, or have no impact outside of the function (i.e. side effects.)
A single emit can only hold half of MongoDB’s maximum BSON document size.
The map function may optionally call emit(key,value) any number of times to create an output document associating key with value.
reduce function
function(key, values) {
   ...//自定義操做
   return result;
}
複製代碼

文檔中的說明:

The reduce function should not access the database, even to perform read operations.
The reduce function should not affect the outside system.
MongoDB will not call the reduce function for a key that has only a single value. The values argument is an array whose elements are the value objects that are 「mapped」 to the key.
MongoDB can invoke the reduce function more than once for the same key. In this case, the previous output from the reduce function for that key will become one of the input values to the next reduce function invocation for that key.
The reduce function can access the variables defined in the scope parameter.
The inputs to reduce must not be larger than half of MongoDB’s maximum BSON document size. This requirement may be violated when large documents are returned and then joined together in subsequent reduce steps.
複製代碼

mapreduce demo //統計每一個年齡的人數,原理同hadoop中的map、reduce方法。 //定義一個js function,以年齡做爲key,進行計數。this表示當前document

String map = "function(){emit(this.age, 1)}";//age : [1,1,1,1]
//js function, 對年齡的全部計數,累加返回key-value
String reduce = "function(key, values){ return Array.sum(values)}";
MapReduceIterable<Document> docs = user.mapReduce(map, reduce);
for (Document doc : docs) {
    System.out.println(doc.toJson());
}
複製代碼

轉載自:www.cnblogs.com/dqrcsc/p/60… 確實寫的很不錯! 因此收集一下該文章了

相關文章
相關標籤/搜索