摘要:踩到許多坑,記錄下一些基于的東西吧首先。王大錘那么查詢的時候,如果要根據查詢班級怎么辦,的查詢也非常簡單。詳情可以查看官方文檔用法
剛接觸mongodb不久。踩到許多坑,記錄下一些基于spring-data-mongodb的東西吧
首先。應該了解下什么情況下使用mongodb,什么情況下用mysql:
業務需要事物,使用mysql,因為mongodb不支持事物
數據量大,但是數據本身價值不大,使用mongodb
數據是非結構化的,且數據量大,使用mongodb
業務未來走向不明確,使用mongodb,方便擴展
鏈接:csdn上關于什么時候使用mongodb的博客
簡單使用下面開始接入spring-data-mongodb
使用maven和spring-boot,pom文件里引入依賴即可
org.springframework.boot spring-boot-starter-data-mongodb
在java代碼里,向集合的實體類上面加上@Document,表示這個類被spring-data-mongodb標識了,可以映射成mongodb里的一個集合,默認名字就是類名,也可以取別名@Document(collection="alias"),示例如下:
@Document public class Example{ private String id; private String picture; }
注意,String類型的id屬性不可缺少,因為mongodb的每個文檔都要有一個id(也可以是其他類型的Id,詳情可以去官方文檔看看),setget方法我就不貼了,用lombok更方便。
這里就可以直接new 一個Example保存了,所以現在建個Repositry用于保存數據
非常簡單只要繼承一個接口就可以
public interface ExampleRepository extends CrudRepository
這里第一個泛型是上面的文檔對象實體,第二個泛型是文檔的id類型
然后就可以直接用exampleRepositry.save(example)保存文檔了。簡單的介紹就到這里
定義一個Repository類,并加上@Repository注解,然后添加自己的方法就可以了,下面上代碼
@Repository public class ExampleAdvancedRepository { @Autowired private MongoOperations mongoOperations; public boolean updateAlias(String id, String alias) { return mongoOperations.updateFirst( query(where("id").is(id)), new Update().set("alias", alias), Example.class).isUpdateOfExisting(); } }
簡單的一個實例,根據Id修改別名,這里一點要說的就是這個id屬性我們傳入進去是String類型,但是monogdbTemplate會將這個id轉成ObjectId,但是只局限于這個文檔屬性名叫id的,如果是其他屬性比如userId,雖然也是ObjectId,但是用where("userId").is(userId)這樣查詢是失敗的,因為這里的userId并沒有轉成ObjectId,正確的做法是where("userId").is(new ObjectId(userId))
數組操作:
增:只要push進數組里就行
public boolean createReply(Reply reply) { return mongoOperations.updateFirst( query(where("id").is(reply.getCommentId())), new Update() .inc("total_replies", 1) .push("replies", reply), Comment.class).isUpdateOfExisting(); }
刪:刪除操作構建一個帶id的DB對象,然后丟進pull方法里就行了,代碼如下
public boolean deleteReply(String commentId, String replyId) { BasicDBObject object = new BasicDBObject(); object.put("id", replyId); return mongoOperations.updateFirst( query(where("id").is(commentId)), new Update() .inc("total_replies", -1) .pull("replies", object), Comment.class).isUpdateOfExisting(); }
這個示例刪除了數組里某個對象,所以要使用傳入一個刪除對象的id,如果數組里存的就是數字,或者字符串就可以直接pull("users","張三")
改:
數組里的對象修改,用占位符即可,代碼如下
public boolean createReplyVote(String commentId, String replyId, String userId) { return mongoOperations.updateFirst( query(where("id").is(commentId).andOperator( where("replies.id").is(new ObjectId(replyId)))), new Update() .addToSet("replies.$.voter_ids", userId) .inc("replies.$.total_voters", 1), Comment.class).isUpdateOfExisting(); }
用占位符$表示數組里的某個匹配的元素
數組里嵌套數組,更新里面數組里的某個對象的屬性
根據上面的方法,發現要用2個占位符,比如set("replies.$.voters.$.name","李四")但是這種寫法是錯誤的。這種情況在mongodb3.6之前是沒辦法解決的,只能將數組嵌套數組的結構改變,變成Map的形式,不能出現兩個占位符的情況,或者修改設計,將里邊的數組拿出來作為獨立的文檔
建立索引可以使用mongodb的腳本去建立,也可以用spring-data-mongo提供的注解建立索引
下面弄個簡單的索引,代碼如下:
@Document @CompoundIndexes({ @CompoundIndex(def = "{"userId": 1, "createdDate": -1}") }) public class Example { private String id; private String userId; private Date createdDate; }
這里建立 了一個簡單的聚合索引,根據userId和createdDate建立的索引。
查看索引是否起效果,可以使用explain方法查看執行計劃,示例如下
collection結構
{ "_id" : ObjectId("5b0cc0f2fde29f2ea0641b16"), "userId" : "1", "createdDate" : ISODate("1995-09-30T16:00:00.000+0000"), "gender" : "MALE" }
執行語句db.Example.find({"userId":"1"}).explain();
可以查看到結果
{ "queryPlanner": { "plannerVersion": 1.0, ... "winningPlan": { "stage": "FETCH", "inputStage": { "stage": "IXSCAN", "keyPattern": { "user_id": 1.0, "created_date": -1.0 }, "indexName": "user_id_1_created_date_-1", "isMultiKey": false, "isUnique": false, "isSparse": false, "isPartial": false, "indexVersion": 1.0, "direction": "forward", "indexBounds": { "user_id": ["["22", "22"]"], "created_date": ["[MaxKey, MinKey]"] } } }, "rejectedPlans": [] } ... }
可以看到關鍵的信息,winningPlan 表示走了索引,然后是具體的信息,rejectedPlans表示沒有走的索引
外鍵引用@DBRef在使用mongdb的時候經常會遇到一個集合嵌套了另一個集合的情況,如果不用引用的話,就得自己手動寫代碼冗余數據,修改的時候就比較麻煩,要同時修改多處。用mongodb提供的$ref 能很好的解決這個問題
首先寫個例子
@Document public class Clazz{ private String id; private String name; @DBRef private People leader; } @Document public class People{ private String id; private String name; private Integer gender; private Integer age; }
每個班級都需要個班主任leader,這個時候用外鍵非常合適使用很簡單,只要在要用到外鍵的字段上,加上@DBRef就可以了。先創建個People集合,保存寫people信息,然后再創建Clazz集合,可以發現Clazz存儲的時候leader變成了一個引用類型。
{ "_id" : ObjectId("5b10a741628e881fc8848d21"), "name" : "王大錘", "leader" : DBRef("People", ObjectId("5b0cf065fde29f25486bf532")), }
那么查詢的時候,如果要根據leader查詢班級怎么辦,@DBRef的查詢也非常簡單。
public Clazz findByLeaderId(String leaderId) { return mongoOperations.findOne( query(where("leader.$id").is(new ObjectId(leaderId))), GhostFriend.class); }
這里注意2個地方,第一個就是引用的時候要加上$id,這樣才能表示此id是引用,第二個地方就是new ObjectId() 在自定義復雜查詢哪里有提到為什么要new ObjectId()
數組操作里有些特殊的場景1.隊列(先進先出)
比如我要保留最新的3個瀏覽記錄,那么就應該建立一個數組,先進的先刪除,永遠保留3個元素
public boolean updateHistory(String id,History history) { return mongoOperations.updateFirst( query(where("id").is(id)), new Update() .push("histories").slice(-3).each(history) People.class).isUpdateOfExisting(); }
這里利用了slice接收int類型的值,表示截取多少個元素,正值則是從前到后保留,負值表示從后到前保留,each則表示加入數組的元素
這里只是做一個簡單的介紹,網上中文資料不多。詳情可以查看mongodb官方文檔slice用法
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19268.html
摘要:踩到許多坑,記錄下一些基于的東西吧首先。王大錘那么查詢的時候,如果要根據查詢班級怎么辦,的查詢也非常簡單。詳情可以查看官方文檔用法 剛接觸mongodb不久。踩到許多坑,記錄下一些基于spring-data-mongodb的東西吧 首先。應該了解下什么情況下使用mongodb,什么情況下用mysql: 業務需要事物,使用mysql,因為mongodb不支持事物 數據量大,但是數據本身...
摘要:踩到許多坑,記錄下一些基于的東西吧首先。先創建個集合,保存寫信息,然后再創建集合,可以發現存儲的時候變成了一個引用類型。王大錘那么查詢的時候,如果要根據查詢班級怎么辦,的查詢也非常簡單。詳情可以查看官方文檔用法 剛接觸mongodb不久。踩到許多坑,記錄下一些基于spring-data-mongodb的東西吧 首先。應該了解下什么情況下使用mongodb,什么情況下用mysql: 業...
摘要:最近公司項目需要支持,每個數據庫地址不同,需求就是修改配置文件,添加或者刪除數據庫配置,重啟系統后就可以完成,不需要額外修改代碼。那怎么來完成數據庫的訪問的呢核心類是,而變量才是完成訪問的關鍵,而這個其實就是。 最近公司項目需要支持multi-tenancy,每個tenant數據庫地址不同,需求就是修改配置文件,添加或者刪除數據庫配置,重啟系統后就可以完成,不需要額外修改代碼。 網上搜...
摘要:最近公司項目需要支持,每個數據庫地址不同,需求就是修改配置文件,添加或者刪除數據庫配置,重啟系統后就可以完成,不需要額外修改代碼。那怎么來完成數據庫的訪問的呢核心類是,而變量才是完成訪問的關鍵,而這個其實就是。 最近公司項目需要支持multi-tenancy,每個tenant數據庫地址不同,需求就是修改配置文件,添加或者刪除數據庫配置,重啟系統后就可以完成,不需要額外修改代碼。 網上搜...
摘要:版本不支持支持為,如果使用并且使用,則會出現提示,編譯出錯。掃描的倉庫目錄,會自動掃描擴展了接口的接口進行注入。 mongodb介紹 MongoDB 是一個基于分布式文件存儲的數據庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴展的高性能數據存儲解決方案。MongoDB 是一個介于關系數據庫和非關系數據庫之間的產品,是非關系數據庫當中功能最豐富,最像關系數據庫的。 MongoD...
閱讀 2486·2021-11-15 18:14
閱讀 1711·2021-10-14 09:42
閱讀 3746·2021-10-11 10:58
閱讀 3939·2021-10-09 09:44
閱讀 2410·2021-09-26 09:55
閱讀 2430·2021-09-24 10:38
閱讀 2025·2021-09-04 16:48
閱讀 3268·2021-09-02 15:21