MongoDB( 五 )MongoDB普通查詢和聚合查詢
目錄
一 : 普通操作
MongoDB的普通查詢MongoTemplate與Mysql的JdbcTemplate或者說是Redis的RedisTemplate別無二致 , 使用方式完全相同;
在使用之間建立一個臨時使用的test集合, 結構如下
db.getCollection("testDocuments").insert( { _id: ObjectId("5fe9439e66730000e70058d0"), name: "huang", age: 21, gender: "男" } ); db.getCollection("testDocuments").insert( { _id: ObjectId("5fe943bb66730000e70058d1"), name: "lu", age: 26, gender: "男" } ); db.getCollection("testDocuments").insert( { _id: ObjectId("5fe943cf66730000e70058d2"), name: "huang", age: 2, gender: "女" } );
例項:
-
插入文件
1 . 使用mongoTemplate直接插入自定義實體類
MongoTestDTO mongoTestDTO = new MongoTestDTO();
mongoTestDTO.setName("huangxiapkuan");
mongoTestDTO.setAge("21");
mongoTestDTO.setGender("男");
mongoTemplate.insert(mongoTestDTO , "testDocuments");
2 . 使用mongoTemplate插入Mongo自帶可動態擴充套件實體類Document.class
import org.bson.Document
// 批量插入 改為 insertMany(List<Document>) 即可
mongoTemplate.insert(new Document("name" , "zhang")
.append("age" , "33").append("gender" , "男"), "testDocuments");
3 . MongoTemplate提供了官方客戶端驅動的封裝,官方客戶端有的方法,它都能呼叫 , 此外還提供了一種更統一的execute方法,
它通過註冊一個回撥,來實現MongoDB操作以及資料回傳:
mongoTemplate.execute(mongodb -> {
mongodb.getCollection("testDocuments").insertOne(new Document("name" , "isnert3")
.append("age" , "33").append("gender" , "男"));
return "sucess";
});
4 . Mongo原生SQL如下:
db.testDocuments.insert({
name: 'huang',
age: 2,
gender: '男'
})
-
刪除文件
1 . 使用mongoTemplate進行刪除操作 , 需要提供Query也就是條件 , 和集合名 , 注意以下使用的 remove()更換為 findAllAndRemove() 則為批量刪除
刪除條件 name = ''insert3'' 的 資料
Query query = new Query();
// Criteria 可自定義建立條件
query.addCriteria(Criteria.where("name").is("insert3"));
mongoTemplate.remove(query , "testDocuments");
刪除條件 _id = ''5feae0eb47801f7dfef1bf2d'' 的 資料
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feae0eb47801f7dfef1bf2d")));
mongoTemplate.remove(query , "testDocuments");
2 . 使用 MongoTemplate.execute 來執行回撥函式 ,用來進行刪除操作 , 官方客戶端有的方法,它都能呼叫
mongoTemplate.execute( mongodb -> {
mongodb.getCollection("testDocuments").deleteOne(new Document("name","isnert3"));
return "sucess";
});
// 又或者
mongoTemplate.execute("testDocuments" ,mongodb -> {
mongodb.deleteOne(new Document("name","isnert3"));
return "sucess";
});
3 . MongoDb原生SQL刪除語句如下
db.testDocuments.remove({
'name': 'insert3'
})
-
更新文件
1 . 使用MongoTemplate.upsert(Query , Update , CollectionName) 進行更新操作
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
Update update = new Update();
update.set("name" , "new_set_values");
UpdateResult result = mongoTemplate.upsert(query, update, "testDocuments");
long count = result.getModifiedCount();
if (count > 0) {
return ApiResult.success("win!~");
}
2 . 使用MongoTemplate.execute() 回撥函式進行更新操作
// 注意這裡 使用的 不是 Update 而是 Updates
String execute = mongoTemplate.execute("testDocuments", mongodb -> {
UpdateResult result = mongodb.updateMany(new Document("name", "isnert3"), Updates.set("name", "upr_execute_name"));
long count = result.getModifiedCount();
if (count > 0) {
return "success";
}
return "error";
});
3 . 使用MongoDb原生SQl 進行更新操作
db.getCollection('testDocuments').updateOne({
name: 'new_set_values'
}, {
$set: {
name: 'Mongo_set_name_new'
}
})
-
查詢操作
由於是測試用
1 . 使用MongoTemplate進行查詢操作
普通查詢
// 查詢所有
List<Document> testDocuments = mongoTemplate.find(new Query(), Document.class, "testDocuments");
// 條件查詢 , 根據_id查詢指定值
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
mongoTemplate.find(query, Document.class, "testDocuments");
// 也可以直接使用MongoTemplate提供的 findById()
mongoTemplate.findById("5feafa9b47801f7dfef1bf2e",Document.class , "testDocuments");
// 條件查詢,查詢特定name值
Query query = new Query();
query.addCriteria(Criteria.where("name").is("huang"));
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");
// 條件查詢,查詢特定name值 ,或者age年齡大於30的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(30));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");
// 條件查詢,查詢特定name值,並且年齡大於20的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(20));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");
//條件查詢 , 分頁查詢 skip(0) 從第0條開始 , limit(2) 查詢兩條
Query query = new Query();
query.skip(0);
query.limit(2);
mongoTemplate.find(query, Document.class, "testDocuments");
//條件查詢 , 排序 sort 可同時針對多個欄位進行排序, 不過當資料量過大時可能會出現記憶體不足
// 具體解決辦法可參照 https://blog.csdn.net/qq_42543063/article/details/111380373
Query query = new Query();
// query.with(Sort.by("age").descending()); // 倒序
query.with(Sort.by("age").ascending()); // 正序
mongoTemplate.find(query, Document.class, "testDocuments");
2 . MongoTemplate提供的回撥與正常方法別無二致, 可按照增刪改的樣例自行探索..........
二 : 聚合操作
MongoDB 中聚合(aggregate)主要用於處理資料(諸如統計平均值,求和等),並返回計算後的資料結果。
有點類似 SQL 語句中的 count(*)。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。
語法
aggregate() 方法的基本語法格式如下所示:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
聚合基礎查詢
一下是本次測是使用的資料
-
聚合查詢、排序、分組、分頁、Concat拼接
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.group("name")
.max("age").as("maxAge")
);
AggregationResults<Document> testDocuments =
mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);
等同於Mongo原生SQL如下:
、
查詢結果 , 可以發現 , name被當做了_id , 且只查詢出來了兩個屬性
{"_id":"upr_execute_name","maxAge":33},{"_id":"huang","maxAge":21},{"_id":"lu","maxAge":26}
可以將上面的聚合操作修改為如下
// 除卻max 函式外 聚合操作還提供了 avg min sum 等常用計算函式
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where("gender").is("男")), // 查詢條件
Aggregation.project("name", "age", "gender")
.andExpression("concat('$gender', '人')").as("genderNew")
,// 可利用 andExpression() 繼續操作某些特定值 加減乘如 或者拼接字串
Aggregation.group("name")
.max("age").as("maxAge") // 取最大年齡 , 別名為 maxAge
.first("name").as("name") // 分組後取該組內第一條name
.first("age").as("age")
.first("gender").as("gender"),
Aggregation.skip(0L), // 始於第幾條 mongo建議使用long型別
Aggregation.limit(2L), // 查詢多少條
Aggregation.sort(Sort.Direction.DESC,
"age" , "name") // 可同時使用多欄位排序 , 需注意當資料量過大時容易造成記憶體不足 具體解決辦法 請參照 https://blog.csdn.net/qq_42543063/article/details/111380373
);
AggregationResults<Document> testDocuments =
mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);
查詢結果樣例為:
{"_id":"huang","maxAge":21,"name":"huang","age":21,"gender":"男"},{"_id":"lu","maxAge":26,"name":"lu","age":26,"gender":"男"}
-
聚合查詢連結串列關聯查詢
為了驗證關聯查詢操作 , 此處需新建一個mongo的集合 , 旨在測試用 , 具體業務不嚴謹!!!
主表為 testDocuments 關聯表為 testRel
// 建立條件集合
List<AggregationOperation> aggregationOptions = new ArrayList<>();
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("testRel") // 指定關聯表
.localField("name") // 關聯表字段
.foreignField("name") // 關聯表字段
.as("rel"); // 關聯表別名
aggregationOptions.add(lookupOperation); // 作為條件新增至條件集合
// 為關聯表建立條件
aggregationOptions.add(Aggregation.match(Criteria.where("rel").elemMatch(Criteria.where("name").ne("").ne(null))));
aggregationOptions.add(Aggregation.group("name")
.max("age").as("maxAge")
.first("name").as("name")
.first("age").as("age")
.first("gender").as("gender")
.first("rel.address").as("assress"));
// 將條件集合建立成聚合操作Aggregation
Aggregation aggregation = Aggregation.newAggregation(aggregationOptions);
AggregationResults<Document> testDocuments =
mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);