mongoTemplate操作內嵌文檔


關系型數據庫中,表與表的關聯關系有1:1,也有1:n的。在java的面向對象的世界里就是主對象嵌子對象,與主對象嵌集合<子對象>的兩種形式。

主對象嵌子對象操作:

新增、修改都直接用如下方法:

mongoTemplate.updateFirst(new Query(criteria), update, clazz, collectionName);

刪除:(刪除內嵌對象列即可)

 update.unset(columnName + ".$");
WriteResult updateFirst = mongoTemplate.updateFirst(query, update, clazz, collectionName);

主對象嵌集合<子對象>的操作:

java對象的例子:

{
    "_id" : "195861",
    "tags" : [
            {
                    "tagId" : NumberLong(766),
                    "optDate" : ISODate("2013-08-12T15:21:02.930Z"),
                    "enable" : true
            },
            {
                    "tagId" : NumberLong(778),
                    "optDate" : ISODate("2013-08-12T15:21:02.930Z"),
                    "enable" : true
            }
    ]

}

MongoTemplate操作的示例:

/**
**給tags數組添加一個元素
*/
@Override
public Response<Integer> addTag(String id, Long tagId) {

    try {
        Tag tag = new Tag(tagId);
        tag.setOptDate(new Date());
        tag.setEnable(true);
        Query query = Query.query(Criteria.where("_id").is(id));
        Update update = new Update();
        update.addToSet("tags", tag);
        mongoTemplate.upsert(query, update, User.class);
    } catch (Exception e) {
        return new Response<Integer>(0);
    }
    return new Response<Integer>(1);
}

/**
**修改tags數組中內嵌文檔指定一個元素的值
*/
@Override
public Response<Integer> disableTag(String id, Long tagId) {

    try {
        Query query = Query.query(Criteria.where("_id").is(id)
                .and("tags.tagId").is(tagId));
        Update update = new Update();
        update.set("tags.$.enable", false);
        mongoTemplate.updateFirst(query, update, User.class);
    } catch (Exception e) {
        return new Response<Integer>(0);
    }
    return new Response<Integer>(1);
}
/**
**刪除tags數組中指定的內嵌文檔
*/
@Override
public Response<Integer> removeTag(String id, Long tagId) {

    try {
        Query query = Query.query(Criteria.where("_id").is(id)
                .and("tags.tagId").is(tagId));
        Update update = new Update();
        update.unset("tags.$");
        mongoTemplate.updateFirst(query, update, User.class);
    } catch (Exception e) {
        return new Response<Integer>(0);
    }

    return new Response<Integer>(1);
}

update.unset這種方法有一個缺陷,會將符合條件的數據修改成null,如果要徹底刪除,則需要使用pull(pull刪除內嵌文檔的時候,student對象的值一定要和被刪除的一模一樣(不懂))

Query query = Query.query(Criteria.where("classId").is("1"));
Update update = new Update();
Student student = new Student("2","lisi",18,"man");
update.pull("Students",student);
mongoTemplate.updateFirst(query, update, "class");

 pull方式刪除內嵌文檔中的行:

Query query = Query.query(Criteria.where("_id").is(id)); 
BasicDBObject s = new BasicDBObject(); 
s.put("tagId", tagid); 
Update update = new Update(); 
update.pull("tags", s); 
mongoTemplate.updateFirst(query, update, User.class);

 

嵌套對象的查詢:

這里需要注意下,如果返回的數據列表是整個對象(外對象+內嵌對象)時,內嵌對象的所有行都會被返回,只有返回值對象指定為內嵌對象時,才能過濾掉內嵌對象集合中不符合條件的記錄。

db.getCollection('tz_member').find({"memberPhotos.memberId":'4'},{"memberPhotos.$":1}).pretty();
db.getCollection('tz_member').find({"member_id":"3","memberPhotos.memberId":{'$in':['4']}},{"memberPhotos.$":1}).pretty();

 

內嵌文檔的主鍵問題

MongoDB CRUD操作(insertupdatefindremove)所有的操作都只在頂級文檔上進行--當然,可以按嵌入文檔中的字段進行篩選。嵌入文檔總是在父文檔中返回。

_id字段是父文檔的必需字段,通常在嵌入文檔中不需要或不存在。如果需要唯一標識符,當然可以創建它們,並且可以使用_id字段來存儲它們,如果這對代碼或心智模型來說是方便的話;更典型的是,它們是以它們所代表的名稱命名的(例如“用戶名”、“其他SystemKey”等等)。MongoDB本身和任何驅動程序都不會自動填充_id字段,但頂層文檔除外。

特別是在Java中,如果希望為_id在嵌入式文檔中,可以使用以下方法來完成:

someEmbeddedDoc._id = new ObjectId();




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM