成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

spring-data-mongodb查詢使用的一些總結(jié)

FuisonDesign / 2184人閱讀

摘要:踩到許多坑,記錄下一些基于的東西吧首先。王大錘那么查詢的時(shí)候,如果要根據(jù)查詢班級(jí)怎么辦,的查詢也非常簡(jiǎn)單。詳情可以查看官方文檔用法

剛接觸mongodb不久。踩到許多坑,記錄下一些基于spring-data-mongodb的東西吧

首先。應(yīng)該了解下什么情況下使用mongodb,什么情況下用mysql:

業(yè)務(wù)需要事物,使用mysql,因?yàn)閙ongodb不支持事物

數(shù)據(jù)量大,但是數(shù)據(jù)本身價(jià)值不大,使用mongodb

數(shù)據(jù)是非結(jié)構(gòu)化的,且數(shù)據(jù)量大,使用mongodb

業(yè)務(wù)未來(lái)走向不明確,使用mongodb,方便擴(kuò)展

鏈接:csdn上關(guān)于什么時(shí)候使用mongodb的博客

簡(jiǎn)單使用

下面開(kāi)始接入spring-data-mongodb
使用maven和spring-boot,pom文件里引入依賴即可


    org.springframework.boot
    spring-boot-starter-data-mongodb

在java代碼里,向集合的實(shí)體類上面加上@Document,表示這個(gè)類被spring-data-mongodb標(biāo)識(shí)了,可以映射成mongodb里的一個(gè)集合,默認(rèn)名字就是類名,也可以取別名@Document(collection="alias"),示例如下:

@Document
public class Example{
    private String id;
    private String picture;
}

注意,String類型的id屬性不可缺少,因?yàn)閙ongodb的每個(gè)文檔都要有一個(gè)id(也可以是其他類型的Id,詳情可以去官方文檔看看),setget方法我就不貼了,用lombok更方便。
這里就可以直接new 一個(gè)Example保存了,所以現(xiàn)在建個(gè)Repositry用于保存數(shù)據(jù)
非常簡(jiǎn)單只要繼承一個(gè)接口就可以
public interface ExampleRepository extends CrudRepository {}
這里第一個(gè)泛型是上面的文檔對(duì)象實(shí)體,第二個(gè)泛型是文檔的id類型
然后就可以直接用exampleRepositry.save(example)保存文檔了。簡(jiǎn)單的介紹就到這里


自定義實(shí)現(xiàn)復(fù)雜查詢,修改等操作

定義一個(gè)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();
    }
}

簡(jiǎn)單的一個(gè)實(shí)例,根據(jù)Id修改別名,這里一點(diǎn)要說(shuō)的就是這個(gè)id屬性我們傳入進(jìn)去是String類型,但是monogdbTemplate會(huì)將這個(gè)id轉(zhuǎn)成ObjectId,但是只局限于這個(gè)文檔屬性名叫id的,如果是其他屬性比如userId,雖然也是ObjectId,但是用where("userId").is(userId)這樣查詢是失敗的,因?yàn)檫@里的userId并沒(méi)有轉(zhuǎn)成ObjectId,正確的做法是where("userId").is(new ObjectId(userId))

數(shù)組操作:
增:只要push進(jìn)數(shù)組里就行

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();
}

刪:刪除操作構(gòu)建一個(gè)帶id的DB對(duì)象,然后丟進(jìn)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();
}

這個(gè)示例刪除了數(shù)組里某個(gè)對(duì)象,所以要使用傳入一個(gè)刪除對(duì)象的id,如果數(shù)組里存的就是數(shù)字,或者字符串就可以直接pull("users","張三")
改:

數(shù)組里的對(duì)象修改,用占位符即可,代碼如下

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();
}

用占位符$表示數(shù)組里的某個(gè)匹配的元素

數(shù)組里嵌套數(shù)組,更新里面數(shù)組里的某個(gè)對(duì)象的屬性
根據(jù)上面的方法,發(fā)現(xiàn)要用2個(gè)占位符,比如set("replies.$.voters.$.name","李四")但是這種寫(xiě)法是錯(cuò)誤的。這種情況在mongodb3.6之前是沒(méi)辦法解決的,只能將數(shù)組嵌套數(shù)組的結(jié)構(gòu)改變,變成Map的形式,不能出現(xiàn)兩個(gè)占位符的情況,或者修改設(shè)計(jì),將里邊的數(shù)組拿出來(lái)作為獨(dú)立的文檔

索引

建立索引可以使用mongodb的腳本去建立,也可以用spring-data-mongo提供的注解建立索引
下面弄個(gè)簡(jiǎn)單的索引,代碼如下:

@Document
@CompoundIndexes({
        @CompoundIndex(def = "{"userId": 1, "createdDate": -1}")
})
public class Example {
    private String id;
    private String userId;
    private Date createdDate;
}

這里建立 了一個(gè)簡(jiǎn)單的聚合索引,根據(jù)userId和createdDate建立的索引。

查看索引是否起效果,可以使用explain方法查看執(zhí)行計(jì)劃,示例如下
collection結(jié)構(gòu)

{ 
    "_id" : ObjectId("5b0cc0f2fde29f2ea0641b16"), 
    "userId" : "1",
    "createdDate" : ISODate("1995-09-30T16:00:00.000+0000"), 
    "gender" : "MALE"
}

執(zhí)行語(yǔ)句db.Example.find({"userId":"1"}).explain();
可以查看到結(jié)果

{
    "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": []
    }
    ...
}

可以看到關(guān)鍵的信息,winningPlan 表示走了索引,然后是具體的信息,rejectedPlans表示沒(méi)有走的索引

外鍵引用@DBRef

在使用mongdb的時(shí)候經(jīng)常會(huì)遇到一個(gè)集合嵌套了另一個(gè)集合的情況,如果不用引用的話,就得自己手動(dòng)寫(xiě)代碼冗余數(shù)據(jù),修改的時(shí)候就比較麻煩,要同時(shí)修改多處。用mongodb提供的$ref 能很好的解決這個(gè)問(wèn)題
首先寫(xiě)個(gè)例子

@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;
}

每個(gè)班級(jí)都需要個(gè)班主任leader,這個(gè)時(shí)候用外鍵非常合適使用很簡(jiǎn)單,只要在要用到外鍵的字段上,加上@DBRef就可以了。先創(chuàng)建個(gè)People集合,保存寫(xiě)people信息,然后再創(chuàng)建Clazz集合,可以發(fā)現(xiàn)Clazz存儲(chǔ)的時(shí)候leader變成了一個(gè)引用類型。

{ 
    "_id" : ObjectId("5b10a741628e881fc8848d21"), 
    "name" : "王大錘",
    "leader" : DBRef("People", ObjectId("5b0cf065fde29f25486bf532")), 
}

那么查詢的時(shí)候,如果要根據(jù)leader查詢班級(jí)怎么辦,@DBRef的查詢也非常簡(jiǎn)單。

public Clazz findByLeaderId(String leaderId) {
    return mongoOperations.findOne(
            query(where("leader.$id").is(new ObjectId(leaderId))),
            GhostFriend.class);
}

這里注意2個(gè)地方,第一個(gè)就是引用的時(shí)候要加上$id,這樣才能表示此id是引用,第二個(gè)地方就是new ObjectId() 在自定義復(fù)雜查詢哪里有提到為什么要new ObjectId()

數(shù)組操作里有些特殊的場(chǎng)景

1.隊(duì)列(先進(jìn)先出)
比如我要保留最新的3個(gè)瀏覽記錄,那么就應(yīng)該建立一個(gè)數(shù)組,先進(jìn)的先刪除,永遠(yuǎn)保留3個(gè)元素

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類型的值,表示截取多少個(gè)元素,正值則是從前到后保留,負(fù)值表示從后到前保留,each則表示加入數(shù)組的元素
這里只是做一個(gè)簡(jiǎn)單的介紹,網(wǎng)上中文資料不多。詳情可以查看mongodb官方文檔slice用法

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/19268.html

相關(guān)文章

  • spring-data-mongodb查詢使用一些總結(jié)

    摘要:踩到許多坑,記錄下一些基于的東西吧首先。王大錘那么查詢的時(shí)候,如果要根據(jù)查詢班級(jí)怎么辦,的查詢也非常簡(jiǎn)單。詳情可以查看官方文檔用法 剛接觸mongodb不久。踩到許多坑,記錄下一些基于spring-data-mongodb的東西吧 首先。應(yīng)該了解下什么情況下使用mongodb,什么情況下用mysql: 業(yè)務(wù)需要事物,使用mysql,因?yàn)閙ongodb不支持事物 數(shù)據(jù)量大,但是數(shù)據(jù)本身...

    jollywing 評(píng)論0 收藏0
  • spring-data-mongodb常用操作

    摘要:踩到許多坑,記錄下一些基于的東西吧首先。先創(chuàng)建個(gè)集合,保存寫(xiě)信息,然后再創(chuàng)建集合,可以發(fā)現(xiàn)存儲(chǔ)的時(shí)候變成了一個(gè)引用類型。王大錘那么查詢的時(shí)候,如果要根據(jù)查詢班級(jí)怎么辦,的查詢也非常簡(jiǎn)單。詳情可以查看官方文檔用法 剛接觸mongodb不久。踩到許多坑,記錄下一些基于spring-data-mongodb的東西吧 首先。應(yīng)該了解下什么情況下使用mongodb,什么情況下用mysql: 業(yè)...

    Michael_Ding 評(píng)論0 收藏0
  • spring-data-mongodb多數(shù)據(jù)庫(kù)訪問(wèn)實(shí)現(xiàn)

    摘要:最近公司項(xiàng)目需要支持,每個(gè)數(shù)據(jù)庫(kù)地址不同,需求就是修改配置文件,添加或者刪除數(shù)據(jù)庫(kù)配置,重啟系統(tǒng)后就可以完成,不需要額外修改代碼。那怎么來(lái)完成數(shù)據(jù)庫(kù)的訪問(wèn)的呢核心類是,而變量才是完成訪問(wèn)的關(guān)鍵,而這個(gè)其實(shí)就是。 最近公司項(xiàng)目需要支持multi-tenancy,每個(gè)tenant數(shù)據(jù)庫(kù)地址不同,需求就是修改配置文件,添加或者刪除數(shù)據(jù)庫(kù)配置,重啟系統(tǒng)后就可以完成,不需要額外修改代碼。 網(wǎng)上搜...

    AaronYuan 評(píng)論0 收藏0
  • spring-data-mongodb多數(shù)據(jù)庫(kù)訪問(wèn)實(shí)現(xiàn)

    摘要:最近公司項(xiàng)目需要支持,每個(gè)數(shù)據(jù)庫(kù)地址不同,需求就是修改配置文件,添加或者刪除數(shù)據(jù)庫(kù)配置,重啟系統(tǒng)后就可以完成,不需要額外修改代碼。那怎么來(lái)完成數(shù)據(jù)庫(kù)的訪問(wèn)的呢核心類是,而變量才是完成訪問(wèn)的關(guān)鍵,而這個(gè)其實(shí)就是。 最近公司項(xiàng)目需要支持multi-tenancy,每個(gè)tenant數(shù)據(jù)庫(kù)地址不同,需求就是修改配置文件,添加或者刪除數(shù)據(jù)庫(kù)配置,重啟系統(tǒng)后就可以完成,不需要額外修改代碼。 網(wǎng)上搜...

    pf_miles 評(píng)論0 收藏0
  • spring+mongodb整合

    摘要:版本不支持支持為,如果使用并且使用,則會(huì)出現(xiàn)提示,編譯出錯(cuò)。掃描的倉(cāng)庫(kù)目錄,會(huì)自動(dòng)掃描擴(kuò)展了接口的接口進(jìn)行注入。 mongodb介紹 MongoDB 是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù)。由 C++ 語(yǔ)言編寫(xiě)。旨在為 WEB 應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案。MongoDB 是一個(gè)介于關(guān)系數(shù)據(jù)庫(kù)和非關(guān)系數(shù)據(jù)庫(kù)之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫(kù)當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫(kù)的。 MongoD...

    warmcheng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<