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());
}
相关文章
相关标签/搜索