java拾遺5----Java操做Mongo入門

Java操做Mongo入門

參考:
http://api.mongodb.com/java/3.2/
http://www.runoob.com/mongodb/mongodb-java.html
https://docs.mongodb.com/manual/html

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中的集合,能夠看作是數據庫中的表。java

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"mongodb

//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鏈接多個條件api

//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、gteapp

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

in:ide

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

and:oop

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);
}

文檔中的說明:

  1. In the map function, reference the current document as this within the function.
  2. The map function should not access the database for any reason.
  3. The map function should be pure, or have no impact outside of the function (i.e. side effects.)
  4. A single emit can only hold half of MongoDB’s maximum BSON document size.
  5. 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;
}

文檔中的說明:

  1. The reduce function should not access the database, even to perform read operations.
  2. The reduce function should not affect the outside system.
  3. 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.
  4. 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.
  5. The reduce function can access the variables defined in the scope parameter.
  6. 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());
}
相關文章
相關標籤/搜索