本文使用 java 来描述对 Mongodb 的相关操作,数据库版本是 3.2.8,驱动版本为 3.2.2。
本文将讨论
如何连接MongoDB文档的 CURD 操作文档的上传和下载首先保证 mongodb 启动了身份验证功能(不启动直接使用ip,Port连接即可)。连接目标可分为三种:单机,集群和副本集。
站在代码的角度,单机和集群的区别就是端口号不同,假设服务器地址和端口号为:192.168.0.8和27017,则连接代码如下:
1234567891011121314 | String user = "admin" ; String pwd = "111111" ; String authDb = "admin" ; String host = "192.168.0.8" ; int port = 27017 ; // 1. 直接连接 MongoCredential credential = MongoCredential.createCredential(user, authDb, pwd.toCharArray()); MongoClient mongoClient = new MongoClient( new ServerAddress(host , port), Arrays.asList(credential)); // 2. 使用连接字符串连接 //mongodb://user:pwd@host:port/?authSource=db String conString = "mongodb://{0}:{1}@{2}:{3}/?authSource={4}" ; MongoClientURI uri = new MongoClientURI(MessageFormat.format(conString, user, pwd, host, port+ "" , authDb)); //注意port为字符串 MongoClient mongoClient = new MongoClient(uri); |
1234567891011 | // 1. 直接连接 MongoClient mongoCli1ent = new MongoClient( Arrays.asList( new ServerAddress( "localhost" , 27017 ), new ServerAddress( "localhost" , 27018 )), Arrays.asList(MongoCredential.createCredential(user, authDb, pwd.toCharArray()))); // 2. 使用连接字符串 //mongodb://user:pwd@host:port, host:port/?authSource=db&replicaSet=rs&slaveOk=true String conStr = "mongodb://{0}:{1}@{2}:{3},{4}:{5}/?authSource={6}&replicaSet={7}&slaveOk=true" ; MongoClientURI uri= new MongoClientURI(MessageFormat.format(conStr, "admin" , "111" , "host1" , "27017" , "host2" , "27018" , "admin" , "rs0" )); MongoClient mongoClient = new MongoClient(uri); |
不管是使用字符串连接,还是直接连接都可以附带一些参数,直接连接时用 MongoClientOptions 类的builder()构造,字符串直接使用 & 拼接在后面就行。常用的参数如下:
replicaSet=name | 副本集名称 | ssl=true|false | 是否使用ssl |
connectTimeoutMS=ms | 连接超时时间 | socketTimeoutMS=ms | socket超时时间 |
maxPoolSize=n | 连接池大小 | safe=true|false | 驱动是否发送getLastError |
journal=true|false | 是否等待将日志刷到磁盘 | ||
authMechanism= | 身份验证方式 | 验证方式有SCRAM-SHA-1 | MONGODB-X509,MONGO-CR,etc |
authSource=string | 验证数据库,默认admin | 采用指定数据库的验证方式 | 3.0之后,默认验证方式为 SCRAM-SHA-1. |
更多详细的参数请见:MongoClientURI
在进行 CURD 操作时,有几个常用的辅助静态类:Filters, Sorts, PRojections,Updates,详细用法请查看:Builders
(1)文档的插入
123456789101112131415 | // 获取待插入集合 mycol MongoDatabase mydb = mongoClient.getDatabase( "myDb" ); MongoCollection<Document> mycol = mydb.getCollection( "myCol" ); // 生成一个文档 Document doc = new Document(); doc.put( "name" , "cyhe" ); doc.put( "blog" , "http://www.cnblogs.com/cyhe/" ); // 也可以使用链式风格构建 new Document( "id" , 1 ).append( "name" , "cyhe" ); // ... etc // 也可以直接将 JSON 转成 BSON doc = Document.parse( "{/"name/":/"cyhe/",/"blog/":/"http://www.cnblogs.com/cyhe//"}" ); // 插入 mycol.insertOne(doc); // 批量插入 mycol.insertMany( new ArrayList<Document>()); |
(2)文档的查找
1234567 | // 查询集合所有文档 List<Document> docs = mycol.find().into( new ArrayList<Document>()); // 直接导入 import static com.mongodb.client.model.Filters.*; 就可以直接使用 and eq 等静态方法 // 查询 age = 20 的文档 Document doc = mycol.find(Filters.eq( "age" , 20 )).first(); // 查询 10<age<20 的文档 返回一个游标 MongoCursor<Document> cur=mycol.find(Filters.and(Filters.gt( "age" , 10 ), Filters.lt( "age" , 20 ))).iterator(); |
(3)文档的更新和删除
12345678 | // 查找并删除名称为 cyhe 的文档 mycol.findOneAndDelete(Filters.eq( "name" , "cyhe" )); // 查找并重命名 mycol.findOneAndUpdate(Filters.eq( "name" , "cyhe" ), Updates.set( "name" , "wQQ" )); // 小于10的都加1 mycol.updateMany(Filters.lt( "size" , 10 ), Updates.inc( "size" , 1 )); // 删除 age 大于 110 的文档 mycol.deleteOne(Filters.gt( "age" , "110" )); |
3. 文档的上传和下载
在Mongodb中,普通文档最大为16M,对于图片,附件来说就显得比较小了,mongodb的处理方式就是使用 GridFS 分块存储。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | // GridFS 默认的名字为 fs,使用默认名称连接 GridFSBucket gridFSBucket = GridFSBuckets.create(mydb); // 使用指定名称连接 GridFSBucket gridFSBucket1 = GridFSBuckets.create(mydb, "imags" ); // 上传文件 // ============================================================================================== InputStream streamToUploadFrom = new FileInputStream( new File( "/tmp/mongodb-tutorial.pdf" )); // 自定义参数 GridFSUploadOptions options = new GridFSUploadOptions() .chunkSizeBytes( 1024 ) .metadata( new Document( "type" , "presentation" )); ObjectId fileId = gridFSBucket.uploadFromStream( "mongodb-tutorial" , streamToUploadFrom, options); // =============================================================================================== // 或者使用 GridFSUploadStream byte [] data = "Data to upload into GridFS" .getBytes(StandardCharsets.UTF_8); GridFSUploadStream uploadStream = gridFSBucket.openUploadStream( "sampleData" , options); uploadStream.write(data); uploadStream.close(); System.out.println( "The fileId of the uploaded file is: " + uploadStream.getFileId().toHexString()); // =============================================================================================== // 下载文件 // =============================================================================================== // 根据生成的 ObjectId 下载 FileOutputStream streamToDownloadTo = new FileOutputStream( "/tmp/mongodb-tutorial.pdf" ); gridFSBucket.downloadToStream(fileId, streamToDownloadTo); streamToDownloadTo.close(); System.out.println(streamToDownloadTo.toString()); // =============================================================================================== // 根据文件名称下载 FileOutputStream streamToDownloadTo = new FileOutputStream( "/tmp/mongodb-tutorial.pdf" ); GridFSDownloadByNameOptions downloadOptions = new GridFSDownloadByNameOptions().revision( 0 ); gridFSBucket.downloadToStreamByName( "mongodb-tutorial" , streamToDownloadTo, downloadOptions); streamToDownloadTo.close(); // =============================================================================================== // 使用 GridFSDownloadStream 根据 ObjectId 下载 GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(fileId); int fileLength = ( int ) downloadStream.getGridFSFile().getLength(); byte [] bytesToWriteTo = new byte [fileLength]; downloadStream.read(bytesToWriteTo); downloadStream.close(); System.out.println( new String(bytesToWriteTo, StandardCharsets.UTF_8)); // =============================================================================================== // 使用 GridFSDownloadStream 根据 名称 下载 GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStreamByName( "sampleData" ); int fileLength = ( int ) downloadStream.getGridFSFile().getLength(); byte [] bytesToWriteTo = new byte [fileLength]; downloadStream.read(bytesToWriteTo); downloadStream.close(); System.out.println( new String(bytesToWriteTo, StandardCharsets.UTF_8)); |
本文只是 Mongodb 操作的冰山一角,更多的用法,会在以后的实战中不断更新完善。更多用法和 API 介绍,详见 MongoDB-Java-3.2
================================================================================================
package com.lgbbigdata.app.user;import com.mongodb.MongoClient;import com.mongodb.MongoCredential;import com.mongodb.ServerAddress;import com.mongodb.client.MongoCollection;import com.mongodb.client.MongoDatabase;import com.mongodb.client.gridfs.GridFSBucket;import com.mongodb.client.gridfs.GridFSBuckets;import com.mongodb.client.gridfs.GridFSDownloadStream;import com.mongodb.client.gridfs.model.GridFSUploadOptions;import com.mongodb.client.model.Filters;import com.mongodb.client.model.Updates;import org.bson.Document;import org.bson.types.ObjectId;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;import java.util.ArrayList;import java.util.Arrays;import java.util.List;/** * Created by ALEX on 2017/2/7. */public class Test { public static void main(String[] args) { String user = "root"; String pwd = "123456"; String authDb = "admin"; String host = "127.0.0.1"; int port = 27017; // 1. 直接连接 MongoCredential credential = MongoCredential.createCredential(user, authDb, pwd.toCharArray()); MongoClient mongoClient = new MongoClient(new ServerAddress(host , port), Arrays.asList(credential)); // 获取待插入集合 mycol MongoDatabase mydb = mongoClient.getDatabase("test"); MongoCollection<Document> mycol = mydb.getCollection("test"); //2.插入数据// Document doc = new Document();// //方式1// doc.put("name", "李四");// doc.put("blog", "http://www.baidu.com/");// mycol.insertOne(doc);// //方式2// doc = new Document("type","方式2").append("name","王五");// mycol.insertOne(doc);// //方式3// doc = Document.parse("{/"type/":/"方式3/",/"name/":/"赵六/"}");//// //插入// mycol.insertOne(doc); //批量插入 //mycol.insertMany(new ArrayList<Document>()); //4.删除 //查找并删除名称为 name 的文档 //mycol.findOneAndDelete(Filters.eq("name", "赵六")); // 查找并重命名 mycol.findOneAndUpdate(Filters.eq("name", "赵六"), Updates.set("name", "zhao6")); // 小于10的都加1 //mycol.updateMany(Filters.lt("size", 10), Updates.inc("size", 1)); // 删除 age 大于 110 的文档 //mycol.deleteOne(Filters.gt("age", "110")); //5.文档的上传和下载 GridFSBucket gridFSBucket = GridFSBuckets.create(mydb); //使用指定名称连接 GridFSBucket gridFSBucket1 = GridFSBuckets.create(mydb, "images"); //上传文件 InputStream streamToUploadFrom = null; try { streamToUploadFrom = new FileInputStream(new File("D://Pictures//Saved Pictures//1190771_123602048841_1.jpg")); } catch (FileNotFoundException e) { e.printStackTrace(); } // 自定义参数 GridFSUploadOptions options = new GridFSUploadOptions() .chunkSizeBytes(10240) .metadata(new Document("type", "presentation")); ObjectId fileId = gridFSBucket.uploadFromStream("mongodb-tutorial1", streamToUploadFrom, options); // =============================================================================================== // 或者使用 GridFSUploadStream// byte[] data = "Data to upload into GridFS".getBytes();// GridFSUploadStream uploadStream = gridFSBucket.openUploadStream("sampleData1", options);// uploadStream.write(data);// uploadStream.close();// System.out.println("The fileId of the uploaded file is: " + uploadStream.getFileId().toHexString()); // 使用 GridFSDownloadStream 根据 名称 下载 GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStreamByName("mongodb-tutorial1"); int fileLength = (int) downloadStream.getGridFSFile().getLength(); byte[] bytesToWriteTo = new byte[fileLength]; downloadStream.read(bytesToWriteTo); downloadStream.close(); System.out.println(new String(bytesToWriteTo)); //3. 查询 List<Document> docs = mycol.find().into(new ArrayList<Document>()); for (int i = 0; i < docs.size(); i++) { System.out.println(docs.get(i)); } Document doc1 = mycol.find(Filters.eq("name", "zhangsan")).first(); }}
新闻热点
疑难解答