关系型数据库中,表与表的关联关系有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();

mongoTemplate操作内嵌文档的更多相关文章

  1. mongodb对数组元素及内嵌文档进行增删改查操作(转)

    from:https://my.oschina.net/132722/blog/168274 比如我有一个user类,他包含一个标签属性,这个标签是一个数组,数组里面的元素是内嵌文档,格式如下: &l ...

  2. MongoDB对数组元素及内嵌文档进行增删改查操作

    比如我有一个user类,他包含一个标签属性,这个标签是一个数组,数组里面的元素是内嵌文档,格式如下: {    "_id" : "195861",    &qu ...

  3. MongoDB内嵌文档操作

    实体定义: [BsonIgnoreExtraElements] public class Person : BaseEntity { public string FirstName { get; se ...

  4. mongodb内嵌文档的查询

    本文转自:http://blog.163.com/wm_at163/blog/static/1321734902012526103825481/ 1 > db.blog.findOne() { ...

  5. mongodb内嵌文档的javaapi,增删改查

    数据结构: {"_id" : "000000001",  //Mongodb默认主键 "UID" : "000000001&quo ...

  6. 学习MongoDB 五: MongoDB查询(数组、内嵌文档)(二)

    一.简介 我们上一篇介绍了db.collection.find()可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段,我们今天介绍了对数组和内嵌文档的查询操作,尤其是 ...

  7. MongoDB-4: 查询(二-数组、内嵌文档)

    一.简介 我们上一篇介绍了db.collection.find()可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段,我们今天介绍了对数组和内嵌文档的查询操作,尤其是 ...

  8. MongoDB 内嵌文档

    MongoDB是文档型的数据库系统,doc是MongoDB的数据单位,每个doc相当于关系型数据库的数据行(row),doc和row的区别在于field的原子性:row中的column是不和分割的原子 ...

  9. mongodb查询内嵌文档

    mongodb查询内嵌文档   假设有这样一个文档: db.XXX.remove(); db.XXX.insert({"id":1, "members":[{& ...

随机推荐

  1. 如何在java中导入jar包

    通常在lib文件夹中存放从外部引入的jar包 所以在项目上右击,new 一个folder,命名为lib 然后把JAR文件复制进去. 然后再在项目上右击,build Path ——configure b ...

  2. NLP-特征选择

    文本分类之特征选择 1 研究背景 对于高纬度的分类问题,我们在分类之前一般会进行特征降维,特征降维的技术一般会有特征提取和特征选择.而对于文本分类问题,我们一般使用特征选择方法. 特征提取:PCA.线 ...

  3. JAVA Properties配置文件的读写

    通常我们就会看到一个配置文件,比如:jdbc.properties,它是以“.properties”格式结尾的.在java中,这种文件的内容以键值对<key,value>存储,通常以“=” ...

  4. Nginx虚拟主机配置模板

    /////////////////////////////写在前头//////////////////////////////////////////Nginx 服务器中文文档:http://www. ...

  5. c++ Const关键字

    转自:http://blog.csdn.net/Eric_Jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根 ...

  6. js外观模式

    外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式类图: 然而对于外观模式而言,是没有一个一般化的类图描述,下面演示一个外观模式的 ...

  7. Linux下Apache的安装与配置

    本文安装的httpd版本为httpd 2.4.4安装之前确保 Development Libraries与Development tools安装上.安装方法参考:http://www.linuxidc ...

  8. Spinner使用二

    Spinner使用二 一.效果图 二.方法及核心函数 三.代码 后面补

  9. 解决: PyInstaller打包后exe文件打开时出现failed to execute script

    def resource_path(self, relative): if hasattr(sys, "_MEIPASS"): return os.path.join(sys._M ...

  10. python向数据库插入中文乱码问题

    1.python向数据库插入中文乱码问题 直接手动insert into 中文 不乱码,但是用程序跑起来就乱码. conn =MySQLdb.connect(host="127.0.0.1& ...