下面简要概述使用MongoDB的Java驱动程序访问数据库。
使用MongoDB的Java驱动非常简单,只要确保将mongo.jar文件添加到classpath中即可。
1).获取连接:
为了连接到MongoDB,需要知道要连接的数据库名称。如果库不存在,MongoDB将创建一个新的库。另外,在连接时需要指定服务器地址和端口。下面展示三种连接本地机器的mydb数据库的方式:
1 | MongoClient mongoClient = new MongoClient(); |
2 | MongoClient mongoClient = new MongoClient( "localhost" ); |
3 | MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); |
4 | MongoClient mongoClient = new MongoClient(Arrays.asList( new ServerAddress( "localhost" , 27017 ), |
5 | new ServerAddress( "localhost" , 27018 ), |
6 | new ServerAddress( "localhost" , 27019 ))); |
8 | DB db = mongoClient.getDB( "mydb" ); |
此时,db对象连接到MongoDB服务器指定的数据库,然后就可以对其进行操作了。
MongoClient类是线程安全和线程共享的。通常在应用程序中对指定的数据库集群只创建一个MongoClient实例。如果由于某些原因需要创建多个MongoClient示例,则需要注意如下内容:
所有资源都进行限制(最大连接数等)应用于每个MongoClient实例;
销毁一个实例时,确保使用MongoClient.close()释放资源。 2).身份认证:
MongoDB可以运行在安全模式下,这种模式使用用户名和密码来进行身份认证来访问数据库。在安全模式下,任何客户端应用程序都必须提供一个用户名和密码在进行任何操作前。在Java驱动中,MongoClient可以使用如下方式:
1 | MongoClient mongoClient = new MongoClient(); |
2 | DB db = mongoClient.getDB( "test" ); |
3 | boolean auth = db.authenticate(myUserName, myPassword); |
如果用户名和密码在数据库中通过验证则反回true,否则返回false。详细的信息可以通过查看MongoDB日志获得。大多是MongoDB在可信环境中不需要身份认证。
3).获取所有集合:
每个数据库都有零到多个集合。可以从db对象中检索出它们:
1 | Set<String> colls = db.getCollectionNames(); |
2 | for (String s : colls) { |
4).获取一个集合:
获取一个集合,只需要指定集合名称调用getCollection(Sring collectionName)方法:
1 | DBCollection coll = db.getCollection( "testCollection" ); |
一旦取得集合对象,就可以对其进行查询,插入数据等操作。
5).设置Write Concern:
对于2.10.0及以后版本,默认的write concern 是WriteConcern.ACKNOWLEDGED,但可以改变默认设置:
1 | mongoClient.setWriteConcern(WriteConcern.JOURNALED); |
wirte concern有很多可选项。另外write concern 默认只可以在数据库,集合甚至单一操作级别进行更改。详细信息可参考api文档http://api.mongodb.org/java/current/index.html。
6).插入一条文档:
一旦取得集合对象,就可以在集合中插入文档。例如,一个json格式表示的文档:
请注意上面文档中有一个内嵌文档。使用BasicDBObject类来创建文档(包括内部文档),然后调用集合的insert()方法插入文档:
1 | BasicDBObject doc = new BasicDBObject( "name" , "MongoDB" ) |
2 | .append( "type" , "database" ) |
4 | .append( "info" , new BasicDBObject( "x" , 203 ).append( "y" , 102 )); |
7).findOne()方法查找集合第一条文档:
使用findOne()方法可以查出上一步插入的文档,这个方法返回一个单一的文档(不同于DBCursor中find()操作的返回值)。这对于只要一条文档或者只关心第一条文档的情况是非常有用的。这里也不需要处理游标。
1 | DBObject myDoc = coll.findOne(); |
2 | System.out.println(myDoc); |
输出:
1 | { "_id" : "49902cde5162504500b45c2c" , |
5 | "info" : { "x" : 203 , "y" : 102}} |
8).添加多条文档:
为了方便查询,向集合中插入多条简单的文档,这些文档格式为;
使用一个循环插入文档:
1 | for ( int i= 0 ; i < 100 ; i++) { |
2 | coll.insert( new BasicDBObject( "i" , i)); |
注意我们可以向同一个集合中插入不同“形状”的文档,这就是MongoDB的模式自由(schema-free)特性。
9).统计集合中文档条数:
目前已经插入101条文档(第一条和100的循环),使用getCount()方法查询:
1 | System.out.println(coll.getCount()); |
将打印出数字101。
10).使用游标查询所有文档:
为了获取到集合中所有的文档,将使用find()方法。find()方法返回一个DBCursor对象,可遍历查询出的文档集合。下面查询所有文档并输出:
1 | DBCursor cursor = coll.find(); |
3 | while (cursor.hasNext()) { |
4 | System.out.println(cursor.next()); |
将会打印出集合中的101条文档。
11).查询单一文档
可以通过给find()方法传递一个参数来查询集合的部分文档。例如,像查出文档的"i"字段的值为71的文档:
1 | BasicDBObject query = new BasicDBObject( "i" , 71 ); |
2 | cursor = coll.find(query); |
4 | while (cursor.hasNext()) { |
5 | System.out.println(cursor.next()); |
将打印出一条文档:
1 | { "_id" : "49903677516250c1008d624e" , "i" : 71 } |
也许你在mongodb的文档和示例代码中看到过$操作符,例如:
1 | db.things.find({j: {$ne: 3}, k: {$gt: 10} }); |
在Java驱动中这些都表示为字符串的key,使用内嵌的DBObject:
01 | query = new BasicDBObject( "j" , new BasicDBObject( "$ne" , 3 )) |
02 | .append( "k" , new BasicDBObject( "$gt" , 10 )); |
03 | cursor = coll.find(query); |
05 | while (cursor.hasNext()) { |
06 | System.out.println(cursor.next()); |
12).查询多个文档:
可以使用一个query条件获取一个文档集合。例如,获取所有“i”>50的文档:
1 | query = new BasicDBObject( "i" , new BasicDBObject( "$gt" , 50 )); |
2 | cursor = coll.find(query); |
4 | while (cursor.hasNext()) { |
5 | System.out.println(cursor.next()); |
查询一个范围内的,如20<i<=30:
01 | query = new BasicDBObject( "i" , new BasicDBObject( "$gt" , 20 ).append( "$lte" , 30 )); |
02 | cursor = testCollection.find(query); |
05 | while (cursor.hasNext()) { |
06 | System.out.println(cursor.next()); |
13).MaxTime
MongoDB2.6引入了查询超时功能:
1 | coll.find().maxTime( 1 , SECONDS).count(); |
上面的例子设置maxTime为一秒,一秒后查询将会中止。
14).批量操作:
MongoDB2.6提供了两种进行批量操作的新命令,包括批量插入、修改和删除操作:
①.有序批量操作:
按顺序执行所有操作,在第一次写错误是输出错误。
②.无序批量操作:
并行执行所有操作,集合所有的错误。无序的批量操作不保证执行顺序。
下面是有序批量操作和无序批量操作的简单例子:
02 | BulkWriteOperation builder = coll.initializeOrderedBulkOperation(); |
03 | builder.insert( new BasicDBObject( "_id" , 1 )); |
04 | builder.insert( new BasicDBObject( "_id" , 2 )); |
05 | builder.insert( new BasicDBObject( "_id" , 3 )); |
06 | builder.find( new BasicDBObject( "_id" , 1 )).updateOne( new BasicDBObject( "$set" , new BasicDBObject( "x" , 2 ))); |
07 | builder.find( new BasicDBObject( "_id" , 2 )).removeOne(); |
08 | builder.find( new BasicDBObject( "_id" , 3 )).replaceOne( new BasicDBObject( "_id" , 3 ).append( "x" , 4 )); |
09 | BulkWriteResult result = builder.execute(); |
12 | builder = coll.initializeUnorderedBulkOperation(); |
13 | builder.find( new BasicDBObject( "_id" , 1 )).removeOne(); |
14 | builder.find( new BasicDBObject( "_id" , 2 )).removeOne(); |
15 | result = builder.execute(); |
17 | MongoDB2. 6 增加了parallelCollectionScan命令,允许使用多个游标读取整个集合: |
18 | ParallelScanOptions parallelScanOptions = ParallelScanOptions |
24 | List<Cursor> cursors = coll.parallelScan(parallelScanOptions); |
25 | for (Cursor pCursor: cursors) { |
26 | while (pCursor.hasNext()) { |
27 | System.out.println((pCursor.next())); |
1).获取数据库列表:
可以调用getBataBaseNames()方法获取到数据库列表:
1 | MongoClient mongoClient = new MongoClient(); |
2 | for (String s : mongoClient.getDatabaseNames()) { |
4 | }<span id= "__kindeditor_bookmark_start_552__" ></span> |
调用mongoClient.getDB()并不会创建一个数据库。只要当一个数据库有写操作时才会被创建,比如创建一个索引,或者创建一个集合或者插入一个文档。
2).删除一个数据库:
MongoClient实例可以通过名称删除一个数据库:
1 | MongoClient mongoClient = new MongoClient(); |
2 | mongoClient.dropDatabase( "databaseToBeDropped" ); |
3).创建一个集合:
有两种方式创建集合,插入文档是当集合不存在时或者调用createCollection命令:
1 | db = mongoClient.getDB( "mydb" ); |
2 | db.createCollection( "testCollection" , new BasicDBObject( "capped" , true ) |
3 | .append( "size" , 1048576 )); |
4).获取集合列表:
可以通过调用db对象的getCollectionNames()方法获取集合列表:
1 | for (String s : db.getCollectionNames()) { |
输出:
5).删除一个集合:
可以通过调用集合对象的deop()方法删除一个集合:
1 | DBCollection testCollection = db.getCollection( "testCollection" ); |
3 | System.out.println(db.getCollectionNames()); |
6).获取一个集合的索引列表:
可以通过调用集合对象的getIndexInfo()方法获取索引列表:
1 | List<DBObject> list = coll.getIndexInfo(); |
2 | for (DBObject o : list) { |
3 | System.out.println(o.get( "key" )); |
将会看到类似下面输出:
1 | { "v" : 1 , "key" : { "_id" : 1 } , "name" : "_id_" , "ns" : "mydb.testCollection" } |
2 | { "v" : 1 , "key" : { "i" : 1 } , "name" : "i_1" , "ns" : "mydb.testCollection" } |
3 | { "v" : 1 , "key" : { "loc" : "2dsphere" } , "name" : "loc_2dsphere" , ... } |
4 | { "v" : 1 , "key" : { "_fts" : "text" , "_ftsx" : 1 } , "name" : "content_text" , ... } |
7).创建一个索引:
MongoDB支持索引,并且它们非常容易的添加到一个集合中。创建一个索引只需要指定需要建立索引的字段,并指定所有升序(1)或者降序(-1)。下面是在i字段上创建一个升序索引:
1 | coll.createIndex( new BasicDBObject( "i" , 1 )); |
8).Geo索引:
MongoDB支持各种地理空间索引。在下面例子中将创建一个“2dsphere ”索引,可以用标准的GeoJson标签查询。创建“2dsphere ”索引需要在文档中指定字符串“2dsphere ”:
1 | coll.createIndex( new BasicDBObject( "loc" , "2dsphere" )); |
有多种方式查询一个“2dsphere ”索引500米内的地方:
01 | BasicDBList coordinates = new BasicDBList(); |
02 | coordinates.put( 0 , - 73.97 ); |
03 | coordinates.put( 1 , 40.77 ); |
04 | coll.insert( new BasicDBObject( "name" , "Central Park" ) |
05 | .append( "loc" , new BasicDBObject( "type" , "Point" ).append( "coordinates" , coordinates)) |
06 | .append( "category" , "Parks" )); |
08 | coordinates.put( 0 , - 73.88 ); |
09 | coordinates.put( 1 , 40.78 ); |
10 | coll.insert( new BasicDBObject( "name" , "La Guardia Airport" ) |
11 | .append( "loc" , new BasicDBObject( "type" , "Point" ).append( "coordinates" , coordinates)) |
12 | .append( "category" , "Airport" )); |
14 | BasicDBList myLocation = new BasicDBList(); |
15 | myLocation.put( 0 , - 73.965 ); |
16 | myLocation.put( 1 , 40.769 ); |
18 | new BasicDBObject( "loc" , |
19 | new BasicDBObject( "$near" , |
20 | new BasicDBObject( "$geometry" , |
21 | new BasicDBObject( "type" , "Point" ) |
22 | .append( "coordinates" , myLocation)) |
23 | .append( "$maxDistance" , 500 ) |
27 | System.out.println(myDoc.get( "name" )); |
9).文本索引:
MongoDB提供了文本索引来支持对字符串内容的文本搜索。文本索引可以包含任何字段的值,它是一个字符串或者字符串数组。创建一个文本索引需要在文档中指定“text”:
1 | coll.createIndex( new BasicDBObject( "content" , "text" )); |
MongoDB2.6中文本索引集成到了主查询语言中,并且默认是启用的:
02 | coll.insert( new BasicDBObject( "_id" , 0 ).append( "content" , "textual content" )); |
03 | coll.insert( new BasicDBObject( "_id" , 1 ).append( "content" , "additional content" )); |
04 | coll.insert( new BasicDBObject( "_id" , 2 ).append( "content" , "irrelevant content" )); |
06 | BasicDBObject search = new BasicDBObject( "$search" , "textual content -irrelevant" ); |
07 | BasicDBObject textSearch = new BasicDBObject( "$text" , search); |
08 | int matchCount = coll.find(textSearch).count(); |
09 | System.out.println( "Text search matches: " + matchCount); |
11 | textSearch = new BasicDBObject( "$text" , search.append( "$language" , "english" )); |
12 | matchCount = coll.find(textSearch).count(); |
13 | System.out.println( "Text search matches (english): " + matchCount); |
15 | BasicDBObject projection = new BasicDBObject( "score" , new BasicDBObject( "$meta" , "textScore" )); |
16 | myDoc = coll.findOne(textSearch, projection); |
17 | System.out.println( "Highest scoring document: " + myDoc); |
将打印出下面内容:
2 | Text search matches (english): 2 |
3 | Highest scoring document: { "_id" : 1 , "content" : "additional content" , "score" : 0.75 } |
更多关于文本索引的信息请参考http://docs.mongodb.org/manual/core/index-text/和