參考:
http://api.mongodb.com/java/3.2/
http://www.runoob.com/mongodb/mongodb-java.html
https://docs.mongodb.com/manual/
=====================================================================
1.dependency
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.2.2</version> </dependency>
2.連接Mongo
2.1.無用戶名密碼驗證
//連接"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
long 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()); }
轉載自:http://www.cnblogs.com/dqrcsc/p/6031389.html
確實寫的很不錯! 所以收集一下該文章了