摘要:學習一個新的數據庫,一般怎么下手呢基本的沒跑了,當可以熟練的增刪改查一個數據庫時,可以說對這個數據庫算是入門了,如果需要更進一步的話,就需要了解下數據庫的特性,比如索引事物鎖分布式支持等本篇博文為的入門篇,將介紹一下基本的查詢操作,在中可以
學習一個新的數據庫,一般怎么下手呢?基本的CURD沒跑了,當可以熟練的增、刪、改、查一個數據庫時,可以說對這個數據庫算是入門了,如果需要更進一步的話,就需要了解下數據庫的特性,比如索引、事物、鎖、分布式支持等
本篇博文為mongodb的入門篇,將介紹一下基本的查詢操作,在Spring中可以怎么玩
原文可參看: 190113-SpringBoot高級篇MongoDB之查詢基本使用姿勢I. 基本使用 0. 環境準備
在正式開始之前,先準備好環境,搭建好工程,對于這一步的詳細信息,可以參考博文: 181213-SpringBoot高級篇MongoDB之基本環境搭建與使用
接下來,在一個集合中,準備一下數據如下,我們的基本查詢范圍就是這些數據
1. 根據字段進行查詢最常見的查詢場景,比如我們根據查詢user=一灰灰blog的數據,這里主要會使用Query + Criteria 來完成
@Component public class MongoReadWrapper { private static final String COLLECTION_NAME = "demo"; @Autowired private MongoTemplate mongoTemplate; /** * 指定field查詢 */ public void specialFieldQuery() { Query query = new Query(Criteria.where("user").is("一灰灰blog")); // 查詢一條滿足條件的數據 Map result = mongoTemplate.findOne(query, Map.class, COLLECTION_NAME); System.out.println("query: " + query + " | specialFieldQueryOne: " + result); // 滿足所有條件的數據 List
上面是一個實際的case,從中可以知道一般的查詢方式為:
Criteria.where(xxx).is(xxx)來指定具體的查詢條件
封裝Query對象 new Query(criteria)
借助mongoTemplate執行查詢 mongoTemplate.findOne(query, resultType, collectionName)
其中findOne表示只獲取一條滿足條件的數據;find則會將所有滿足條件的返回;上面執行之后,刪除結果如
query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { } | specialFieldQueryOne: {_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帥氣逼人的碼農界老秀} query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { } | specialFieldQueryAll: [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帥氣逼人的碼農界老秀}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帥氣逼人的碼農界老秀3}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}]2. and多條件查詢
前面是只有一個條件滿足,現在如果是要求同時滿足多個條件,則利用org.springframework.data.mongodb.core.query.Criteria#and來斜街多個查詢條件
/** * 多個查詢條件同時滿足 */ public void andQuery() { Query query = new Query(Criteria.where("user").is("一灰灰blog").and("age").is(18)); Map result = mongoTemplate.findOne(query, Map.class, COLLECTION_NAME); System.out.println("query: " + query + " | andQuery: " + result); }
刪除結果如下
query: Query: { "user" : "一灰灰blog", "age" : 18 }, Fields: { }, Sort: { } | andQuery: {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}3. or或查詢
and對應的就是or,多個條件中只要一個滿足即可,這個與and的使用有些區別, 借助org.springframework.data.mongodb.core.query.Criteria#orOperator來實現,傳參為多個Criteria對象,其中每一個表示一種查詢條件
/** * 或查詢 */ public void orQuery() { // 等同于 db.getCollection("demo").find({"user": "一灰灰blog", $or: [{ "age": 18}, { "sign": {$exists: true}}]}) Query query = new Query(Criteria.where("user").is("一灰灰blog") .orOperator(Criteria.where("age").is(18), Criteria.where("sign").exists(true))); List
執行后輸出結果為
query: Query: { "user" : "一灰灰blog", "$or" : [{ "age" : 18 }, { "sign" : { "$exists" : true } }] }, Fields: { }, Sort: { } | orQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}] query: Query: { "$or" : [{ "age" : 18 }, { "sign" : { "$exists" : true } }] }, Fields: { }, Sort: { } | orQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}, {_id=5c3b0538e3ac8e8d2d392390, user=二灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}]4. in查詢
標準的in查詢case
/** * in查詢 */ public void inQuery() { // 相當于: Query query = new Query(Criteria.where("age").in(Arrays.asList(18, 20, 30))); List
輸出
query: Query: { "age" : { "$in" : [18, 20, 30] } }, Fields: { }, Sort: { } | inQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}]5. 數值比較
數值的比較大小,主要使用的是 get, gt, lt, let
/** * 數字類型,比較查詢 > */ public void compareBigQuery() { // age > 18 Query query = new Query(Criteria.where("age").gt(18)); List
輸出
query: Query: { "age" : { "$gt" : 18 } }, Fields: { }, Sort: { } | compareBigQuery: [{_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}] query: Query: { "age" : { "$gte" : 18 } }, Fields: { }, Sort: { } | compareBigQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}] query: Query: { "age" : { "$lt" : 20 } }, Fields: { }, Sort: { } | compareSmallQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}] query: Query: { "age" : { "$lte" : 20 } }, Fields: { }, Sort: { } | compareSmallQuery: [{_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}]6. 正則查詢
牛逼高大上的功能
/** * 正則查詢 */ public void regexQuery() { Query query = new Query(Criteria.where("user").regex("^一灰灰blog")); Listresult = mongoTemplate.find(query, Map.class, COLLECTION_NAME); System.out.println("query: " + query + " | regexQuery: " + result); }
輸出
query: Query: { "user" : { "$regex" : "^一灰灰blog", "$options" : "" } }, Fields: { }, Sort: { } | regexQuery: [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帥氣逼人的碼農界老秀}, {_id=5c3afacde3ac8e8d2d392389, user=一灰灰blog2, desc=帥氣逼人的碼農界老秀2}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帥氣逼人的碼農界老秀3}, {_id=5c3afafbe3ac8e8d2d39238b, user=一灰灰blog4, desc=帥氣逼人的碼農界老秀4}, {_id=5c3afb0ae3ac8e8d2d39238c, user=一灰灰blog5, desc=帥氣逼人的碼農界老秀5}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}]7. 查詢總數
統計常用,這個主要利用的是mongoTemplate.count方法
/** * 查詢總數 */ public void countQuery() { Query query = new Query(Criteria.where("user").is("一灰灰blog")); long cnt = mongoTemplate.count(query, COLLECTION_NAME); System.out.println("query: " + query + " | cnt " + cnt); }
輸出
query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { } | cnt 58. 分組查詢
這個對應的是mysql中的group查詢,但是在mongodb中,更多的是通過聚合查詢,可以完成很多類似的操作,下面借助聚合,來看一下分組計算總數怎么玩
/* * 分組查詢 */ public void groupQuery() { // 根據用戶名進行分組統計,每個用戶名對應的數量 // aggregate([ { "$group" : { "_id" : "user" , "userCount" : { "$sum" : 1}}}] ) Aggregation aggregation = Aggregation.newAggregation(Aggregation.group("user").count().as("userCount")); AggregationResultsans = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class); System.out.println("query: " + aggregation + " | groupQuery " + ans.getMappedResults()); }
注意下,這里用Aggregation而不是前面的Query和Criteria,輸出如下
query: { "aggregate" : "__collection__", "pipeline" : [{ "$group" : { "_id" : "$user", "userCount" : { "$sum" : 1 } } }] } | groupQuery [{_id=一灰灰blog, userCount=5}, {_id=一灰灰blog2, userCount=1}, {_id=一灰灰blog4, userCount=1}, {_id=二灰灰blog, userCount=1}, {_id=一灰灰blog5, userCount=1}]9. 排序
sort,比較常見的了,在mongodb中有個有意思的地方在于某個字段,document中并不一定存在,這是會怎樣呢?
/** * 排序查詢 */ public void sortQuery() { // sort查詢條件,需要用with來銜接 Query query = Query.query(Criteria.where("user").is("一灰灰blog")).with(Sort.by("age")); Listresult = mongoTemplate.find(query, Map.class, COLLECTION_NAME); System.out.println("query: " + query + " | sortQuery " + result); }
輸出結果如下,對于沒有這個字段的document也被查出來了
query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { "age" : 1 } | sortQuery [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帥氣逼人的碼農界老秀}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帥氣逼人的碼農界老秀3}, {_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}]10. 分頁
數據量多的時候,分頁查詢比較常見,用得多就是limit和skip了
/** * 分頁查詢 */ public void pageQuery() { // limit限定查詢2條 Query query = Query.query(Criteria.where("user").is("一灰灰blog")).with(Sort.by("age")).limit(2); Listresult = mongoTemplate.find(query, Map.class, COLLECTION_NAME); System.out.println("query: " + query + " | limitPageQuery " + result); // skip()方法來跳過指定數量的數據 query = Query.query(Criteria.where("user").is("一灰灰blog")).with(Sort.by("age")).skip(2); result = mongoTemplate.find(query, Map.class, COLLECTION_NAME); System.out.println("query: " + query + " | skipPageQuery " + result); }
輸出結果表明,limit用來限制查詢多少條數據,skip則表示跳過前面多少條數據
query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { "age" : 1 } | limitPageQuery [{_id=5c2368b258f984a4fda63cee, user=一灰灰blog, desc=帥氣逼人的碼農界老秀}, {_id=5c3afaf4e3ac8e8d2d39238a, user=一灰灰blog, desc=帥氣逼人的碼農界老秀3}] query: Query: { "user" : "一灰灰blog" }, Fields: { }, Sort: { "age" : 1 } | skipPageQuery [{_id=5c3b003ee3ac8e8d2d39238f, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, sign=hello world}, {_id=5c3afb1ce3ac8e8d2d39238d, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=18.0}, {_id=5c3b0031e3ac8e8d2d39238e, user=一灰灰blog, desc=帥氣逼人的碼農界老秀6, age=20.0}]11. 小結
上面給出的一些常見的查詢姿勢,當然并不全面,比如我們如果需要查詢document中的部分字段怎么辦?比如document內部結果比較復雜,有內嵌的對象或者數組時,嵌套查詢可以怎么玩?索引什么的又可以怎么利用起來,從而優化查詢效率?如何通過傳說中自動生成的_id來獲取文檔創建的時間戳?
先留著這些疑問,后面再補上
II. 其他 0. 項目工程:spring-boot-demo
module: mongo-template
相關博文: 181213-SpringBoot高級篇MongoDB之基本環境搭建與使用
1. 一灰灰Blog一灰灰Blog個人博客 https://blog.hhui.top
一灰灰Blog-Spring專題博客 http://spring.hhui.top
一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛
2. 聲明盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
微博地址: 小灰灰Blog
QQ: 一灰灰/3302797840
3. 掃描關注一灰灰blog
知識星球
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19461.html
摘要:學習一個新的數據庫,一般怎么下手呢基本的沒跑了,當可以熟練的增刪改查一個數據庫時,可以說對這個數據庫算是入門了,如果需要更進一步的話,就需要了解下數據庫的特性,比如索引事物鎖分布式支持等本篇博文為的入門篇,將介紹一下基本的查詢操作,在中可以 學習一個新的數據庫,一般怎么下手呢?基本的CURD沒跑了,當可以熟練的增、刪、改、查一個數據庫時,可以說對這個數據庫算是入門了,如果需要更進一步的...
摘要:本篇博文為的中一篇,前面介紹簡單的查詢使用,這一篇重點則放在插入數據基本使用首先是準備好基本環境,可以參考博文高級篇之基本環境搭建與使用高級篇之查詢基本使用姿勢新增一條數據一個基本數據稱為,和不一樣,沒有強制約束哪些字段,可以隨 本篇博文為mongodb的curd中一篇,前面介紹簡單的查詢使用,這一篇重點則放在插入數據; I. 基本使用 首先是準備好基本環境,可以參考博文 1812...
摘要:原文高級篇之修改基本使用姿勢本篇依然是中的一篇,主要介紹的更新,主要內容如下常見類型成員的修改數組類型成員的增刪改類型成員的增刪改基本使用首先是準備好基本環境,可以參考博文高級篇之基本環境搭建與使用高級篇之查詢基本使用姿勢在開 原文: 190218-SpringBoot高級篇MongoDB之修改基本使用姿勢 本篇依然是MongoDB curd中的一篇,主要介紹document的更新,...
摘要:雙刃劍的學習和避坑是一把雙刃劍,它對數據結構的要求并不高。第二某些銀行顯示的金額不是實時的。第三步創建封裝類的管理類,針對不同的實體類,需要配置不同的。 雙刃劍MongoDB的學習和避坑 MongoDB 是一把雙刃劍,它對數據結構的要求并不高。數據通過key-value的形式存儲,而value的值可以是字符串,也可以是文檔。所以我們在使用的過程中非常方便。正是這種方便給我們埋下了一顆顆...
摘要:聲明構造函數,作用是把從數據庫取出的數據實例化為對象。該構造函數傳入的值為從中取出的數據省略接口提供增刪改查接口實現提供增刪改查接口實現提供了一個類似于的設計的類。 本文快速入門,MongoDB 結合SpringBoot starter-data-mongodb 進行增刪改查 1、什么是MongoDB ? MongoDB 是由C++語言編寫的,是一個基于分布式文件存儲的開源數據庫系統。...
閱讀 2536·2023-04-25 19:47
閱讀 3383·2019-08-29 17:18
閱讀 856·2019-08-29 15:26
閱讀 3360·2019-08-29 14:17
閱讀 1115·2019-08-26 13:49
閱讀 3339·2019-08-26 13:22
閱讀 3023·2019-08-26 10:44
閱讀 2693·2019-08-23 16:51