【引言】
毕竟现在MongoDB还是出于成长阶段,所以现在网上相关的资料很少,而且大部分还都是针对于MongoDB的老版本的。再加上MongoDB的频繁升级、重大更新等等,导致菜鸟学习的难度增大。
好了,前几篇讲的都是MongoDB数据库相关的知识,最终,还是要与java来接轨(当然,卤煮是搞java开发的)。看了看现在的java驱动版本截至目前2016年8月27日为止为3.3,与网上搜索到的教程很多写法不一致,所以卤煮在此决定研究一下官网的教程,希望能对自己或者其他人有一点帮助,足矣...
ps:本文只是官网的一个快速入门,让我这样的菜鸟能了解个大概,有些地方可能还需要深入的学习才能读懂。本人水平有限,有些地方有删减,翻译不到位的地方还请各位看官海涵并留言指出,本人一定虚心学习改正,以免误导!
O shit!突然想起来,MongoDB的java驱动也不好找,忘了给大家提供干货了,特地快马加鞭的补上:mongo-java-driver-3.3.0.jar下载
【翻译篇】
官网原文地址:戳这里
MongoDB驱动程序快速入门
以下的所有示例代码来自QuickTour.java文件,可以在驱动程序源代码中找到。
1.创建一个连接
下面的例子展示了通过5种方式来连接本地的数据库 mydb,如果数据库不存在,MongoDB会自动创建。
- // 简单直接的连接数据库,默认为本机地址localhost,端口号27017
- MongoClient mongoClient = new MongoClient();
- // 或者像这样指定连接地址
- MongoClient mongoClient = new MongoClient( "localhost" );
- // 或者像这样指定连接地址和端口号
- MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
- // 或者像这样连接到一个副本集,需要提供一个列表
- MongoClient mongoClient = new MongoClient(
- Arrays.asList(new ServerAddress("localhost", 27017),
- new ServerAddress("localhost", 27018),
- new ServerAddress("localhost", 27019)));
- // 或者使用连接字符串
- MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017,localhost:27018,localhost:27019");
- MongoClient mongoClient = new MongoClient(connectionString);
- // 获取到数据库对象mydb,如果不存在则自动创建
- MongoDatabase database = mongoClient.getDatabase("mydb");
MongoClient
一个MongoClient实例实际上表示的是一个数据库连接池,即使是多线程,你也只需要一个MongoClient类的实例。
注意
通常,对于一个数据库集群你仅仅只需要创建一个MongoClient实例,并且使用它来贯穿你的整个应用程序。当创建多个实例的时候:
- 注意每个MongoClient实例的所有资源使用限制(最大连接数等等)
- 销毁实例,请确保你调用
MongoClient.close()
来清理资源
2.获取一个集合
要获取一个集合来进行更多操作,需要为getCollection()方法指定一个集合的名称。
下面的例子表示获取名称为 test 的集合:
- MongoCollection<Document> collection = database.getCollection("test");
3.插入一个文档
一旦你有了Collection集合对象了,你可以往集合中插入一个文档。例如,观察下面的JSON文档,这个文档中又包含了一个嵌入式的文档字段 info
- {
- "name" : "MongoDB",
- "type" : "database",
- "count" : 1,
- "info" : {
- x : 203,
- y : 102
- }
- }
使用java驱动程序中的Document类来创建文档,你同样也可以使用这个类来创建嵌入式的文档。
- Document doc = new Document("name", "MongoDB")
- .append("type", "database")
- .append("count", 1)
- .append("info", new Document("x", 203).append("y", 102));
使用insertOne()方法来向集合中插入文档
- collection.insertOne(doc);
下面的例子将会创建多个文档:
- { "i" : value }
- List<Document> documents = new ArrayList<Document>();
- for (int i = 0; i < 100; i++) {
- documents.add(new Document("i", i));
- }
- collection.insertMany(documents);
5.统计集合中的文档数量
到现在为止我们已经插入了101个文档(我们在循环中创建了100个,加上第一个文档),我们可以使用count()方法来检查一下它们是否都已经插入成功了。下面的代码应该输出101:
使用find()方法来查询集合。
6.1查询集合中的第一个文档
要获取集合中的第一个文档,需要在find()方法操作后调用first()方法,collection.find().first() 返回第一个文档或者空,而不是一个游标。这对于只需要匹配单个文档或者你只需要第一个文档的查询很有用处。
下面的例子会打印出从集合中找到的第一个文档:
- Document myDoc = collection.find().first();
- System.out.println(myDoc.toJson());
- { "_id" : { "$oid" : "551582c558c7b4fbacf16735" },
- "name" : "MongoDB", "type" : "database", "count" : 1,
- "info" : { "x" : 203, "y" : 102 } }
- MongoCursor<Document> cursor = collection.find().iterator();
- try {
- while (cursor.hasNext()) {
- System.out.println(cursor.next().toJson());
- }
- } finally {
- cursor.close();
- }
- for (Document cur : collection.find()) {
- System.out.println(cur.toJson());
- }
7.使用查询过滤器得到一个单一的文档
我们可以创建一个过滤器并传递给find()方法,来得到集合中文档的子集。例如,我们想要查询字段“i”的值为71的文档,我们可以这样做:
- import static com.mongodb.client.model.Filters.*;
- myDoc = collection.find(eq("i", 71)).first();
- System.out.println(myDoc.toJson());
然后它就会仅仅输出一个文档:
- { "_id" : { "$oid" : "5515836e58c7b4fbc756320b" }, "i" : 71 }
注意
可以使用 Filters
, Sorts
, Projections
和Updates类来创建简单明了的查询方式。
8.查询一组文档
我们可以使用查询来获得集合中的一组文档。例如,如果我们想得到 i>50 的文档,我们可以这样写:
- // 现在使用范围查询来得到一个大点的子集
- Block<Document> printBlock = new Block<Document>() {
- @Override
- public void apply(final Document document) {
- System.out.println(document.toJson());
- }
- };
- collection.find(gt("i", 50)).forEach(printBlock);
我们还可以得到一个范围,比如说,50<i<=100:
我们也可以使用Sorts帮助类来进行排序文档。我们通过在FindIterable 上调用sort()方法来添加一个排序查询,下面我们使用exists()方法和descending("i")方法来排序:
- myDoc = collection.find(exists("i")).sort(descending("i")).first();
- System.out.println(myDoc.toJson());
有时候我们并不需要文档中的所有数据,Projections帮助类可以帮助我们在查询操作中创建投影参数。下面我们将进行整理,通过使用Projections.execludeId()方法来排除文档中的“_id”字段,并且输出第一个匹配的文档:
- myDoc = collection.find().projection(excludeId()).first();
- System.out.println(myDoc.toJson());
11.聚合
有时候,我们需要聚合存储在MongoDB中的数据,Aggregates 帮助类为每种类型的聚合提供了构建。
下面我们将通过一个简单的两步骤转换,来计算 i*10的值。首先我们使用Aggregates.match()方法来查询所有i>0的文档,然后我们使用Agreegates.project()方法重塑文档,再结合$multiply操作来计算“ITimes10”的值:
- collection.aggregate(asList(
- match(gt("i", 0)),
- project(Document.parse("{ITimes10: {$multiply: ['$i', 10]}}")))
- ).forEach(printBlock);
12.更新文档
使用updateOne()方法来更新0个或1个文档(如果没有和过滤器匹配的话则是0个),并且要指定过滤器和更新后的文档。这里我们使用Updates.set()方法来更新符合i=10的第一个文档,并且设置i的值为110:
- collection.updateOne(eq("i", 10), set("i", 110));
- UpdateResult updateResult = collection.updateMany(lt("i", 100), inc("i", 100));
- System.out.println(updateResult.getModifiedCount());
13.删除文档
使用deleteOne()方法来删除0个或1个文档
- <span style="font-size:18px;">collection.deleteOne(eq("i", 110));</span>
- DeleteResult deleteResult = collection.deleteMany(gte("i", 100));
- System.out.println(deleteResult.getDeletedCount());
14.批量操作
这些新命令允许批量插入/更新/删除操作的执行,这里有两种批量操作的方式(不知道理解的对不对):
-
有序批量操作。
执行所有预定操作,当出现写入错误时会停止操作。
-
无序批量操作。
执行所有操作,并报告所有的错误。
无序批量操作不保证所有操作的执行。
我们来看下两个简单的例子:
- // 2. 有序批量操作,调用是有保证的
- collection.bulkWrite(
- Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
- new InsertOneModel<>(new Document("_id", 5)),
- new InsertOneModel<>(new Document("_id", 6)),
- new UpdateOneModel<>(new Document("_id", 1),
- new Document("$set", new Document("x", 2))),
- new DeleteOneModel<>(new Document("_id", 2)),
- new ReplaceOneModel<>(new Document("_id", 3),
- new Document("_id", 3).append("x", 4))));
- // 2. 无序批量操作,调用没有保证
- collection.bulkWrite(
- Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
- new InsertOneModel<>(new Document("_id", 5)),
- new InsertOneModel<>(new Document("_id", 6)),
- new UpdateOneModel<>(new Document("_id", 1),
- new Document("$set", new Document("x", 2))),
- new DeleteOneModel<>(new Document("_id", 2)),
- new ReplaceOneModel<>(new Document("_id", 3),
- new Document("_id", 3).append("x", 4))),
- new BulkWriteOptions().ordered(false));