一、目标:
- 获取mongodb collection中document个数
- 获取collection的首个document最外层字段数和字段名
- 处理mongodb用户名和密码包含特殊字符的情况
二、MongoDB和关系型数据句比如Oracle的对应关系
Oracle | table | row | column |
---|---|---|---|
MongoDB | collection | document | key |
三、MongoDB的特点和代码
3.1 MongoDB的document
MongoDB的document和Oracle的row不同,document的内容就好比是json,基本元素是键值对,可以嵌套,比如:
{ "_id" : ObjectId("5b9a2be39ec29f55d6b15fe3"), "student" : [ { "student-A" : "A" }, { "student-B" : "B" } ] }
与json类似,同一个collection中的不同document的字段数和字段类型是可以不同的;本文只介绍获取首个document最外层字段数和字段名的方法
3.2 MongoDB的url
mongodb://username:password@127.0.0.1:27017/admin
# 其中:
# mongodb://是固定的,admin为数据库名;
# 如果当前数据库设置了用户名密码访问的话(默认无密访问),需要加上username:password,分别为用户名和密码;
# 127.0.0.1:27017为host ip和端口;
但是有时候username和password可能会包含一些特殊符号,比如@和:,而这些特殊符号是作为MongoDB url的分隔符,如果不经处理的话,使用客户端程序去访问MongoDB server就会出现url无法正确解析的情况,那么这个时候就需要对特殊符号进行编码。
3.3 附上scala代码
pom.xml中添加依赖:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.6.4</version>
</dependency>
scala代码
import java.util
import com.mongodb.{BasicDBObject, MongoClient, MongoClientURI}
import org.slf4j.LoggerFactory
object MongoUtil {
def queryDocCntAndFieldCnt(url: String, userName: String, password: String,
dbName: String, collectionName: String): (Long, Int) = {
var docCount: Long = 0L
var fieldCount: Int = 0
var mongodbInputUri = url
if (userName != null && (!userName.equals(""))) {
mongodbInputUri = encodeUrl(url, userName, password)
}
val mongoClientUri = new MongoClientURI(mongodbInputUri)
val mongoClient = new MongoClient(mongoClientUri)
val collection = mongoClient.getDatabase(dbName).getCollection(collectionName)
docCount = collection.count()
// MongoDB是非关系型数据库,如果collection中无document,则无法获取字段信息
if (docCount > 0) {
val command = new BasicDBObject
val sql = String.format("Object.keys(db.%s.findOne())", collectionName)
command.put("eval", sql)
val fieldArr = mongoClient.getDatabase(dbName).runCommand(command).get("retval").asInstanceOf[util.ArrayList[String]].toArray()
fieldCount = fieldArr.length
}
(docCount, fieldCount)
}
def encodeUrl(url: String, userName: String, password: String): String = {
var mongodbInputUri = url
// 如果当前数据库设置了用户名登陆的话,对user/password中的特殊字符@和:进行编码
if (userName != null && (!userName.equals(""))) {
val newUser = userName.replace("@","%40").replace(":","%3A")
val newPassword = password.replace("@","%40").replace(":","%3A")
val userPassword = newUser.concat(":").concat(newPassword).concat("@")
val strBuilder = new StringBuilder(url)
mongodbInputUri = strBuilder.insert(10, userPassword).toString()
}
mongodbInputUri
}
}