学习主题:MongoDb3
学习目标:
掌握如下内容
mongodb数据库前提:
1 连接 MongoDB 数据库
1.1 创建工程(maven:jar)
在 POM 文件中添加 MongoDB 驱动坐标
<!-添加 MongoDB驱动坐标 -->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java -driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.8.2</version>
</dependency>
</dependencies>
未封装代码:
public class MongoDBDemo {
public static void main(String[] args) {
//创建连接对象
MongoClient client = new MongoClient("192.168.41.145", 27017);
//获取MongoDB数据库
MongoDatabase database = client.getDatabase("develop");
//获取MongoDB中的集合
MongoCollection collection = database.getCollection("dev");
//连接成功显示ok
System.out.println("OK.................");
}
}
1.2 创建 MongoDB 连接
封装 MongoDBUtil
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
/**
* @author cyj
* @date 2019-11-04 15:11
*/
public class MongoDBUtil {
private static MongoClient client=null;
static {
if (client==null){
client=new MongoClient("192.168.41.145", 27017);
}
}
//获取MongoDB数据库
public static MongoDatabase getDatabas(String dbName){
return client.getDatabase(dbName);
}
//获取MongoDB中的集合
public static MongoCollection getCollection(String dbName,String collName){
return getDatabas(dbName).getCollection(collName);
}
}
测试:
public class MongoDBDemo {
public static void main(String[] args) {
MongoDBUtil.getCollection("develop","dev");
//连接成功显示ok
System.out.println("OK.................");
}
}
1.3 创建 MongoDB 的认证连接
封装 MongoDBAuthUtil
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import java.util.Arrays;
/**
* 创建MongoDB链接-使用用户认证
* @author cyj
* @date 2019-11-04 15:34
*/
public class MongoDBAuthUtil {
private static MongoClient client = null;
static {
if(client == null){
//创建一个封装用户认证信息
MongoCredential credential = MongoCredential.createCredential("sxt", "develop", "sxt".toCharArray());
//封装MongoDB的地址与端口
ServerAddress address = new ServerAddress("192.168.41.145", 27017);
client = new MongoClient(address, Arrays.asList(credential));
}
}
//获取MongoDB数据库
public static MongoDatabase getDatabase(String dbName){
return client.getDatabase(dbName);
}
//获取MongoDB中的集合
public static MongoCollection getCollection(String dbName, String collName){
MongoDatabase database = getDatabase(dbName);
return database.getCollection(collName);
}
}
1.4 创建 MongoDB 的池连
封装 MongoDBPoolUtil
package com.bjsxt;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
/**
* 使用池连的方式获取连接
*/
public class MongoDBPoolUtil {
private static MongoClient client = null;
static{
if(client == null){
MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
builder.connectionsPerHost(10);//每个地址的大连接数
builder.connectTimeout(5000);//连接超时时间
builder.socketTimeout(5000);//设置读写操作超时时间
ServerAddress address = new ServerAddress("192.168.70.156",27017);
client = new MongoClient(address,builder.build());
}
}
//获取MongoDB数据库
public static MongoDatabase getDatabase(String dbName){
return client.getDatabase(dbName);
}
//获取MongoDB中的集合
public static MongoCollection getCollection(String dbName, String collName){
MongoDatabase database = getDatabase(dbName);
return database.getCollection(collName);
}
}
1.5 创建 MongoDB 的认证池连
封装 MongoDBAuthPoolUtil
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
/**
* @author cyj
* @date 2019-11-04 16:27
*/
public class MongoDBAuthPoolUtil {
private static MongoClient client=null;
static {
if (client==null){
MongoClientOptions.Builder builder=new MongoClientOptions.Builder();
builder.connectionsPerHost(10);//每个地址的大连接数
builder.connectTimeout(5000);//连接超时时间
builder.socketTimeout(5000);//设置读写操作超时时间
MongoCredential credential=MongoCredential.createCredential("sxt", "develop", "sxt".toCharArray());
ServerAddress address = new ServerAddress("192.168.41.145", 27017);
client = new MongoClient(address,credential,builder.build());
}
}
//获取MongoDB数据库
public static MongoDatabase getDatabase(String dbName){
return client.getDatabase(dbName);
}
//获取MongoDB中的集合
public static MongoCollection getCollection(String dbName, String collName){
return getDatabase(dbName).getCollection(collName);
}
//创建集合
public static void createCollection(String dbName,String collName){
getDatabase(dbName).createCollection(collName);
}
//删除集合
public static void dropCollection(MongoCollection coll){
coll.drop();
}
}
2 操作集合
2.1 创建集合
//创建集合
public static void createCollection(String dbName,String collName){
getDatabase(dbName).createCollection(collName);
}
2.2 获取集合
//获取MongoDB中的集合
public static MongoCollection getCollection(String dbName, String collName){
return getDatabase(dbName).getCollection(collName);
}
2.3 删除集合
//删除集合
public static void dropCollection(MongoCollection coll){
coll.drop();
}
3 操作文档
3.1 添加文档
3.1.1 添加单个文档 3.1.2 添加多个文档
import com.mongodb.client.MongoCollection;
import org.bson.Document;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author cyj
* @date 2019-11-04 16:55
*/
public class InsertDocument {
public static void main(String[] args) {
InsertDocument docu = new InsertDocument();
//docu.inesrtSingleDocument();
docu.insertManyDocument();
}
/**
* 添加单个文档
*/
public void inesrtSingleDocument(){
//获取集合
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
// {}---->Document
//append(String key,Object value)---->{key:value}
Document docu=new Document();
docu.append("username","lisi").append("userage",26).append("userdesc","Very Good").append("userlike", Arrays.asList(new String[]{"Music","Sport"}));
collection.insertOne(docu);
}
/**
* 文档的批量添加
*/
public void insertManyDocument(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
List<Document> list = new ArrayList<Document>();
for(int i=0;i<5;i++){
Document docu = new Document();
docu.append("username","zhangsan"+i);
docu.append("userage",20+i);
docu.append("userdesc","OK"+i);
docu.append("userlike",Arrays.asList(new String[]{"Music","Sport"}));
list.add(docu);
}
collection.insertMany(list);
}
}
运行结果:注:因为我是在develop库下创建的sxt用户,所以创建devtest集合时不用切换到bjsxt用户
3.2 更新文档
3.2.1 更新单个文档单个键
/**
* 更新单个文档单个键
* --> db.devtest.update({username:{$eq:"lisi"}},{$set:{userage:28}})
*/
public void updateSingleDocumentSingleKey(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
//更新文档
//Filters封装了条件的一个工具类 {$set:{userage:28}}
collection.updateOne(Filters.eq("username","lisi"),new Document("$set",new Document("userage",28)));
}
3.2.2 更新单个文档多个键
/**
* 更新单个文档多个键 -->db.devtest.update({username:{$eq:"zhangsan0"}},{$set:{userage:18,userdesc:"Very Good"}})
*/
public void updateSingleDocumentManyKey(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
collection.updateOne(Filters.eq("username","zhangsan0"),new Document("$set",new Document("userage",18).append("userdesc","Very Good")));
}
3.2.3 更新多个文档中的单个键
/**
* 更新多个文档单个键
* --> db.devtest.update({username:{$ne:"zhangsan0"}},{$set:{userage:18,userdesc:"Very Good"}},{multi:true})
*/
public void updateManyDocumentSingleKey(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
collection.updateMany(Filters.ne("username",null),new Document("$set",new Document("userdesc","Very Good")));
}
3.2.4 更新多个文档中的多个键
/**
* 更新多个文档多个键
* --> db.devtest.update({username:{$ne:null}},{$set:{userage:20,userdesc:"OK"}},{multi:true})
*/
public void updateManyDocumentManyKey(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
collection.updateMany(Filters.ne("username",null),new Document("$set",new Document("userdesc","OK").append("userage",20)));
}
3.2.5 更新文档中的数组
/**
* 更新文档中的数组
* {$push:{}}
* -->db.devtest.update({username:{$eq:"lisi"}},{$push:{userlike:"Art"}})
*/
public void updateDocumentArray(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
collection.updateOne(Filters.eq("username","lisi"),new Document("$push",new Document("userlike","Art")));
}
3.3 查询文档
3.3.1 查询全部文档
/**
* 查询全部文档
* -->db.devtest.find()
*/
public void selectDocumentAll(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
//返回的是一个文档的迭代器
FindIterable<Document> iterable = collection.find();
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.2 根据_id 查询文档-$eq
/**
* 根据_id查询文档
* --> db.devtest.find("5dbfe840e755c006c0b03217")
*/
public void selectDocumentById(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable<Document> iterable = collection.find(Filters.eq("_id",new ObjectId("5d398cd64b022206d87d168e")));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
ObjectId()是一个对象,所以需要new ,而不能直接传字符串
------------
3.3.3 查询多个文档-$gt
/**
* 根据年龄查询文档,条件是年龄大于19
* --> db.devtest.find({userage:{$gt:19}})
*/
public void selectDocumentConditionByGt(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.gt("userage",19));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.4 查询多个文档-$type
/**
* 根据年龄查询文档,添加是年龄的值是整数类型(number)
* --> db.devtest.find({userage:{$type:"number"}})
*/
public void selectDocumentConditionByType(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.type("userage","number"));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.5 查询多个文档-$in
/**
* 查询用户的名字为 zhangsan1,zhangsan2
*--> db.devtest.find({username:{$in:["zhangsan1","zhangsan2"]}})
*--> db.devtest.find({$or:[{username:"zhangsan1"},{username:"zhangsan2"}]})
*/
public void selectDocumentConditionByIn(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.in("username","zhangsan1","zhangsan2"));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.6 查询多个文档-$nin
/**
* 查询用户的名字不是 zhangsan1,zhangsan2
*--> db.devtest.find({username:{$nin:["zhangsan1","zhangsan2"]}})
*/
public void selectDocumentConditionByNin(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.nin("username","zhangsan1","zhangsan2"));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.7 查询多个文档-$regex
/**
* 查询用户的名字是z开头2结尾的。
*--> db.devtest.find({username:/^z.*2$/}) Pattern:java.util包
*/
public void selectDocumentConditionByRegex(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.regex("username", Pattern.compile("^z.*2$")));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.8 逻辑运算符-$and
/**
* 查询用户username是zhangsan1并且年龄为20岁的用户
* --> db.devtest.find({$and:[{username:{$eq:"zhangsan1"}},{userage:{$eq:20}}]})
*/
public void selectDocumentConditionUseAnd(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.and(Filters.eq("username","zhangsan1"),Filters.eq("userage",20),Filters.eq("userdesc","OK")));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.9 逻辑运算符-$or
/**
* 查询用户要求username是list,或者userage是20 或者 userdesc是Very Good
* --> db.devtest.find({$or:[{username:{$eq:"lisi"}},{userage:{$eq:20}},{userdesc:{$eq:"Very Good"}}]})
*/
public void selectDocumentConditionUseOr(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.or(Filters.eq("username","lisi"),Filters.eq("userage",20),Filters.eq("userdesc","Very Good")));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.10 逻辑运算符-$and 与$or 联合使用
/**
* 查询文档中username为lisi并且年龄为20岁,或者userdesc为Very Good
* --> db.devtest.find({$or:[{$and:[{username:{$eq:"lisi"}},{userage:{$eq:20}}]},{userdesc:{$eq:"Very Good"}}]})
*/
public void selectDocumentConditionAndOr(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.or(Filters.and(Filters.eq("username","lisi"),Filters.eq("userage",20)),Filters.eq("userdesc","Very Good")));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.3.11 查询文档-排序处理
/**
* 查询文档中username是z开头的,根据username对结果做降序排序。1升序排序, -1降序排序规则 $sort:{username,-1}
* --> db.devtest.find({username:/^z/}).sort({username:-1})
*/
public void selectDocumentSorting(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
FindIterable iterable = collection.find(Filters.regex("username", Pattern.compile("^z"))).sort(new Document("username",-1));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike"));
}
}
3.4 日期操作
3.4.1 插入系统当前日期
/**
* 插入系统当前日期
*--> db.devtest.insert({username:"wangwu",userage:22,userdesc:"Very Good",userlike:["Music","Art"],userbirth:new Date()})
*/
public void insertDocumentSystemDate(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop", "devtest");
Document docu=new Document();
docu.put("username","wangwu");
docu.put("userage",22);
docu.put("userdesc","Very Good");
docu.put("userlike", Arrays.asList(new String[]{"Music","Art"}));
docu.put("userbirth",new Date());
collection.insertOne(docu);
- }
3.4.2 插入指定日期
创建日期处理工具类
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author cyj
* @date 2019-11-04 19:30
*/
public class DateUtil {
/**
* Date To String
*/
public static String dateToString(String parten, Date date){
SimpleDateFormat format=new SimpleDateFormat(parten);
return format.format(date);
}
/**
* String To Date
*/
public static Date stringToDate(String parten,String date){
SimpleDateFormat format=new SimpleDateFormat(parten);
Date d=null;
try {
d = format.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return d;
}
}
添加指定日期
/**
* 插入指定日期
* --> db.devtest.insert({username:"zhaoliu",userage:24,userdesc:"Very Good",userlike:["Music","Art"],userbirth:new Date("2019-11-05T13:32:13")})
*/
public void insertDocumentCustoDate(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
Date date= DateUtil.stringToDate("yyyy-MM-dd HH:mm:ss","2019-11-05 13:32:13");
Document docu = new Document();
docu.put("username","zhaoliu");
docu.put("userage",24);
docu.put("userdesc","Very Good");
docu.put("userlike", Arrays.asList(new String[]{"Music","Art"}));
docu.put("userbirth",date);
collection.insertOne(docu);
}
3.4.3 查询日期-$eq
/**
* 查询日期:查询用的生日为2019-05-01 13:32:13的用户信息
*--> db.devtest.find({userbirth:{$eq:new Date("2019-11-05T13:32:13")}})
*/
public void selectDocumentDateUseEq(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
Date date = DateUtil.stringToDate("yyyy-MM-dd HH:mm:ss","2019-11-05 13:32:13");
FindIterable iterable = collection.find(Filters.eq("userbirth", date));
MongoCursor<Document> cursor = iterable.iterator();
while (cursor.hasNext()){
Document docu = cursor.next();
String temp=DateUtil.dateToString("yyyy-MM-dd HH:mm:ss",(Date) docu.get("userbirth"));
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike")+"\t"+temp);
}
}
3.4.4 查询日期-$gt
/**
* 查询日期:查询用的生日大于2019-01-01 00:00:00的用户信息
*--> db.devtest.find({userbirth:{$gt:new Date("2019-01-01T00:00:00")}})
*/
public void selectDocumentDateUseGt(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
Date date = DateUtil.stringToDate("yyyy-MM-dd HH:mm:ss","2019-01-01 00:00:00");
FindIterable iterable = collection.find(Filters.gt("userbirth",date));
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
String temp = DateUtil.dateToString("yyyy-MM-dd HH:mm:ss",(Date) docu.get("userbirth"));
System.out.println(docu.get("username")+"\t"+docu.get("userage")+"\t"+docu.get("userdesc")+"\t"+docu.get("userlike")+"\t"+temp);
}
}
3.5 聚合操作
3.5.1 聚合操作-计算文档总数-$sum
需求:查询集合中的文档数量
Mongo Shell:db.dev.aggregate([{$group:{_id:null,count:{$sum:1}}}])
/**
* 需求:查询集合中的文档数量
Mongo Shell:db.dev.aggregate([{$group:{_id:null,count:{$sum:1}}}])
*/
public void selectDocumentAggregateCount(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document sum = new Document();
sum.put("$sum",1);
Document count = new Document();
count.put("_id",null);
count.put("count",sum);
Document group = new Document();
group.put("$group",count);
List<Document> list = new ArrayList<Document>();
list.add(group);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("count"));
}
}
3.5.2 聚合操作-计算值的总和-$sum
需求:查询集合中所有 size 键中的值的总和
Mongo Shell:db.dev.aggregate([{$group:{_id:null,totalSize:{$sum:"$size"}}}])
/**
* 需求:查询集合中所有size键中的值的总和
Mongo Shell:db.dev.aggregate([{$group:{_id:null,totalSize:{$sum:"$size"}}}])
*/
public void selectDocumentAggregateSum(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document sum = new Document();
sum.put("$sum","$size");
Document totalSize = new Document();
totalSize.put("_id",null);
totalSize.put("totalSize",sum);
Document group = new Document();
group.put("$group",totalSize);
List<Document> list = new ArrayList<Document>();
list.add(group);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("totalSize"));
}
}
3.5.3 聚合操作-在分组中计算值的总和-$sum
需求:对 title 进行分组,计算每组中的 size 的总和
Mongo Shell:db.dev.aggregate([{$group:{_id:"$title",totalSize:{$sum:"$size"}}}])
/**
* 需求:对title进行分组,计算每组中的size的总和
Mongo Shell:db.dev.aggregate([{$group:{_id:"$title",totalSize:{$sum:"$size"}}}])
*/
public void selectDocumentAggregateGroupBySum(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document sum= new Document();
sum.put("$sum","$size");
Document totalSize = new Document();
totalSize.put("_id","$title");
totalSize.put("totalSize",sum);
Document group = new Document();
group.put("$group",totalSize);
List<Document> list = new ArrayList<Document>();
list.add(group);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("totalSize"));
}
}
3.5.4 聚合操作-分组前的数据过滤-$match
需求:查询 dev 集合有多少文档的 size 大于 200。
Mongo Shell: db.dev.aggregate([{$match:{size:{$gt:200}}},{$group:{_id:null,totalSize:{$sum:1}}}])
/**
* 需求:查询dev集合有多少文档的size大于200。
Mongo Shell:
db.dev.aggregate([{$match:{size:{$gt:200}}},{$group:{_id:null,totalSize:{$sum:1}}}])
*/
public void selectDocumentAggregateGroupByWhere(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document gt = new Document();
gt.put("$gt",200);
Document size = new Document();
size.put("size",gt);
Document match = new Document();
match.put("$match",size);
Document sum = new Document();
sum.put("$sum",1);
Document totalSize = new Document();
totalSize.put("_id",null);
totalSize.put("totalSize",sum);
Document group = new Document();
group.put("$group",totalSize);
List<Document> list = new ArrayList<Document>();
list.add(match);
list.add(group);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("totalSize"));
}
}
3.5.5 聚合操作-分组后的数据过滤-$match
需求:查询 dev 集合,根据 title 分组计算出每组的 size 的总和,并过滤掉总和小于 200 的文档。
Mongo Shell: db.dev.aggregate([{$group:{_id:"$title",totalSize:{$sum:"$size"}}},{$match:{totalSize:{$gt: 200}}}])
/**
* 需求:查询dev集合,根据title分组计算出每组的size的总和,并过滤掉总和小于200的文档。
Mongo Shell:
db.dev.aggregate([{$group:{_id:"$title",totalSize:{$sum:"$size"}}},{$match:{totalSize:{$gt:200}}}])
*/
public void selectDocumentAggregateGroupByHaving(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document sum = new Document();
sum.put("$sum","$size");
Document totalSize = new Document();
totalSize.put("_id","$title");
totalSize.put("totalSize",sum);
Document group = new Document();
group.put("$group",totalSize);
//{$match:{totalSize:{$gt:200}}}
Document gt = new Document();
gt.put("$gt",200);
Document mtotalSize = new Document();
mtotalSize.put("totalSize",gt);
Document match = new Document();
match.put("$match",mtotalSize);
List<Document> list = new ArrayList<Document>();
list.add(group);
list.add(match);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu.get("totalSize"));
}
}
3.5.6 聚合操作-$project-聚合投影约束
需求:查询 dev 集合,将数组中的内容拆分显示,并只显示 title 键与 tags 键的值。
Mongo Shell: db.dev.aggregate([{$unwind:"$tags"},{$project:{_id:0,tags:"$tags",title:"$title"}}])
/**
* 需求:查询dev集合,将数组中的内容拆分显示,并只显示title键与tags键的值。
Mongo Shell:
db.dev.aggregate([{$unwind:"$tags"},{$project:{_id:0,tags:"$tags",title:"$title"}}])
*/
public void selectDocumentProject(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document unwind = new Document();
unwind.put("$unwind","$tags");
Document pro = new Document();
pro.put("_id",0);
pro.put("tags","$tags");
pro.put("title","$title");
Document project = new Document();
project.put("$project",pro);
List<Document> list = new ArrayList<Document>();
list.add(unwind);
list.add(project);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
System.out.println(cursor.next());
}
}
3.5.7 聚合操作-$project-字符串处理
需求:查询 dev 集合,将数组中的内容拆分显示。将 title 字段和 tags 字段的值拼接为 一个完整字符串并在 Title_Tags 字段中显示。
Mongo Shell: db.dev.aggregate([{$unwind:"$tags"},{$project:{_id:0,Title_Tags:{$concat:["$title","-","$tag s"]}}}])
/**
* 需求:查询dev集合,将数组中的内容拆分显示。将title字段和tags字段的值拼接为一个完整字符串并在Title_Tags字段中显示。
Mongo Shell:
db.dev.aggregate([{$unwind:"$tags"},{$project:{_id:0,Title_Tags:{$concat:["$title","-","$tags"]}}}])
*/
public void selectDocumentProjectConcat(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document unwind = new Document();
unwind.put("$unwind","$tags");
Document concat = new Document();
concat.put("$concat", Arrays.asList(new String[]{"$title","-","$tags"}));
Document title = new Document();
title.put("_id",0);
title.put("Title_Tags",concat);
Document project = new Document();
project.put("$project",title);
List<Document> list = new ArrayList<Document>();
list.add(unwind);
list.add(project);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
System.out.println(cursor.next());
}
}
3.5.8 聚合操作-$project 算术运算
需求:查询dev集合中数据,显示title和 size字段,为size字段数据做加 1 操作,显示字段命名为 New_Size。排除那些没有 size 键的文档。
Mongo Shell: db.dev.aggregate([{$match:{size:{$ne:null}}},{$project:{_id:0,title:1,New_Size:{$add:["$si ze",1]}}}])
/**
* 需求:查询dev集合中数据,显示title和size字段,为size字段数据做加1操作,显示字段命名为New_Size。排除那些没有size键的文档。
Mongo Shell:
db.dev.aggregate([{$match:{size:{$ne:null}}},{$project:{_id:0,title:1,New_Size:{$add:["$size",1]}}}])
*/
public void selectDocumentProjectAdd(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document ne = new Document();
ne.put("$ne",null);
Document size = new Document();
size.put("size",ne);
Document match = new Document();
match.put("$match",size);
//{$project:{_id:0,title:1,New_Size:{$add:["$size",1]}}}
Document add = new Document();
add.put("$add",Arrays.asList(new Object[]{"$size",1}));
Document new_Size = new Document();
new_Size.put("_id",0);
new_Size.put("title",1);
new_Size.put("New_Size",add);
Document project = new Document();
project.put("$project",new_Size);
List<Document> list = new ArrayList<Document>();
list.add(match);
list.add(project);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
System.out.println(cursor.next());
}
}
3.5.9 聚合操作-$project 日期处理
需求:查询 devtest 集合查询那些有生日的用户,并按照 YYYY 年 mm 月 dd 日 HH:MM:SS 格式显示日期。
Mongo Shell: db.devtest.aggregate([{$match:{userbirth:{$ne:null}}},{$project:{ 自定义日期格式:{$dateToString:{format:"%Y 年%m 月%d 日 %H:%M:%S",date:"$userbirth"}}}}])
/**
* 需求:查询devtest集合查询那些有生日的用户,并按照YYYY年mm月dd日 HH:MM:SS格式显示日期。
* 注意:如果直接在MongoDB中做日期的格式化处理,那么是按照表示UTC时间来处理的,会少8个小时。建议在程序中
* 通过java.util.Date来做日期的转换。
Mongo Shell:
db.devtest.aggregate([{$match:{userbirth:{$ne:null}}},{$project:{自定义日期格式:{$dateToString:{format:"%Y年%m月%d日 %H:%M:%S",date:"$userbirth"}}}}])
*/
public void selectDocumentProjectDate(){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","devtest");
Document ne = new Document();
ne.put("$ne",null);
Document birth = new Document();
birth.put("userbirth",ne);
Document match = new Document();
match.put("$match",birth);
//{$project:{自定义日期格式:{$dateToString:{format:"%Y年%m月%d日 %H:%M:%S",date:"$userbirth"}}}}
Document format = new Document();
format.put("format","%Y年%m月%d日 %H:%M:%S");
format.put("date","$userbirth");
Document dateToString = new Document();
dateToString.put("$dateToString",format);
Document custoDate = new Document();
custoDate.put("自定义日期格式",dateToString);
Document project = new Document();
project.put("$project",custoDate);
List<Document> list = new ArrayList<Document>();
list.add(match);
list.add(project);
AggregateIterable iterable = collection.aggregate(list);
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
System.out.println(cursor.next());
}
}
3.6 分页查询
3.6.1 使用 skip 与 limit 方法分页
/**
* 通过skip与limit方法实现分页
* @param pageIndex 当前页
*/
public void selectDocumentByPageUseSkipAndLimit(int pageIndex){
int page=(pageIndex-1)*2; //第几页=(当前页-1)*每页显示数量
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
//可以给查询添加条件
Document condition=new Document("size",new Document("$ne",null));
long total = collection.countDocuments(condition);//返回条件的总条数,也可以放在查询中
System.out.println("总条数:"+total);
//long total = collection.countDocuments();
FindIterable iterable = collection.find(condition).skip(page).limit(2);//显示返回满足条件的数据
// FindIterable iterable = collection.find().skip(page).limit(2);
MongoCursor<Document> cursor = iterable.iterator();
while (cursor.hasNext()){
Document document = cursor.next();
System.out.println(document);
}
}
3.6.2 优化分页查询(skip方法比较耗时,因为要换算出现在应该跳过多少文档,skip会扫描所有的文档。所以文档较多的时候就不适合使用 )
使用条件判断替换 skip 方法 (跳页很麻烦)
/**
* 通过条件判断实现分页
* @param pageIndex 当前页
* @param pageSize 每页显示多少条
* @param lastId 后文档的某一个key的值,作为查询下一个数据的判断条件。此处随便给一个都行
*/
public void selectDocumentByPageUseCondition(int pageIndex,int pageSize,String lastId){
MongoCollection collection = MongoDBAuthPoolUtil.getCollection("develop","dev");
Document condition = new Document("size",new Document("$ne",null));
long countNum = collection.countDocuments(condition);//满足条件的有多少条
System.out.println(countNum);
FindIterable iterable = null;
if(pageIndex == 1){//查的是页,页不需要跳过
iterable = collection.find(condition).limit(pageSize);
}else{//查的不是页
if(lastId != null){
condition.append("_id",new Document("$gt",new ObjectId(lastId)));
iterable = collection.find(condition).limit(pageSize);
}
}
MongoCursor<Document> cursor = iterable.iterator();
while(cursor.hasNext()){
Document docu = cursor.next();
System.out.println(docu);
}
}
测试:
public static void main(String[] args) {
SelectDocumentByPage page = new SelectDocumentByPage();
//page.selectDocumentByPageUseSkipAndLimit(1);
}