设计MongoDB数据模型的时候,我们需要转变以往设计关系型数据模型时的思维。即便是针对一个关系中不同集合的数量规模,我们的模型也将有很大的不同。...如用户和任务模块,任务是系统定期发布,分配给相应用户完成,这意味着我们对任务的操作也将比较复杂。这样的情况下,显然是分开不同集合进行存储,然后让person集合引用task_id数组。...“实体”和“值对象”的部分概念,主要还是看这些数据模型在系统中是否有较大较复杂的操作可能。...一个基本的原则是考虑两边统一引用对方的ObjectId,适当冗余部分信息。...通用建议 以下给出一张较通用的建议表,仅供参考 内嵌 引用 子文档较小 子文档较大 数据不会定期更改 数据经常改变 最终数据一致即可 中间阶段数据也必须一致 文档数据小额增加 文档数据大幅增加 数据通常需要执行二次查询
MongoDB的引用式数据模型是一种将数据拆分为多个文档的方法,用于管理大量数据或需要频繁更新的数据。引用式数据模型使用一个文档来引用另一个文档,而不是将所有数据存储在单个文档中。...引用式数据模型使用一个文档来引用另一个文档,而不是将所有数据存储在单个文档中。在MongoDB中,引用通常使用ObjectID类型的字段来表示。...ObjectID是一个12字节的唯一标识符,由一个时间戳、机器ID、进程ID和随机值组成。通过ObjectID,可以轻松地引用另一个文档。...引用字段通常使用ObjectID类型的字段来表示。引用文档引用式数据模型中的引用文档是存储实际数据的文档。引用文档可以包含单个数据实体或数据结构的一部分。...本地字段"customerId"是订单集合中用于引用客户集合的字段。外部字段"_id"是客户集合中的主键字段。聚合管道还使用$unwind阶段来展开$lookup阶段的输出数组。
MongoDB是一个基于文档模型的NoSQL数据库,它的数据建模与传统的关系型数据库有很大的不同。在MongoDB中,数据是以文档的形式存储的,文档是一种类似于JSON的数据格式,非常灵活和扩展。...数据模型的基本概念在MongoDB中,数据是以文档的形式存储的,每个文档都是一个具有一定结构的JSON对象。MongoDB将文档组织成集合(collection),每个集合类似于传统数据库中的表。...MongoDB中的文档由键值对组成,每个键都是字符串类型,值可以是各种类型,包括字符串、数值、数组、嵌套文档等。...如果需要使用嵌套文档,需要确保子文档的数据在父文档中的任何位置都是一致的。如果有多个文档需要更新相同的数据,需要使用事务来确保一致性。...2.3 扩展性MongoDB的文档模型具有很好的扩展性,但需要在设计文档模式时考虑到。在将数据分布到多个节点时,需要确保数据的相关性。
Aggregation Operation) MapReduce 编程模型 在本篇中,重点讲解聚合管道和单目的聚合操作,MapReduce 编程模型会在后续的文章中讲解。...其中,match、group 都是阶段操作符,而阶段 group 中用到的 sum 是表达式操作符。...8.1.1 阶段操作符 8.1.1 阶段操作符 使用阶段操作符之前,我们先看一下 article 集合中的文档列表,也就是范例中用到的数据。...$indexOfCP 在字符串中搜索子字符串的出现,并返回第一次出现的UTF-8代码点索引。如果未找到子字符串,则返回“-1”。 $split 根据分隔符将字符串拆分为子字符串。返回子字符串数组。...$indexOfArray 在数组中搜索指定值的出现,并返回第一次出现的数组索引。如果未找到子字符串,则返回“-1”。 $isArray 确定操作数是否为数组。返回一个布尔值。
One-to-N基本方法 MongoDB中One-to-N模型可以简单通过在父文档中嵌入一组子文档(sub-documents),但并不意味着你应该这么做。...你需要更精细地判断以下的情况: 基数关系 实现 优缺点 One-to-Few 嵌入(embedding) 优点:不必执行单独的查询来获取子文档的信息 缺点:无法将嵌入的信息作为独立实体( stand-alone...但是在具体不同的业务中,仍然需要一些方法来优化One-to-N的模型。 实现 双向引用(Two-Way referencing) 1. one数组引用N 2....-> One:One的数组中不只引用ObjectID,还冗余保存其他的N中的字段。...如果有上百个以上的N,不要整个嵌入,如果有上千个N,也不要使用ObjectID数组引用。巨量数组就不要嵌入。
x" : 1, "y" : 30 } 上述查找命令跳过 1 个文档,限制输出 10 个,以 age 子段正序排序(大于 0 为正序,小于 0 位反序)输出结果。...在实际工作中你很可能会用到ObjectId, 所以我们在这里也使用它) 显然,要找到Leto的所有员工,只要执行: db.employees.find({manager: ObjectId("4d85c7039ab0fd70a117d730...4.1.1 数组和嵌入文档(Embedded Documents) MongoDB 没有连接并不意味着它没有其他的优势。还记得我们曾说过 MongoDB 支持数组并把它当成文档中的一级对象吗?..."), ObjectId("4d85c7039ab0fd70a117d732")] }) 需要注意的是,在这种情况下,有些文档中的 manager 可能是一个向量,而其他的却是数组。...: {allowed_gholas: 5, spice_ration: 10}}) 这不是说您就应该低估嵌入文档的作用,也不是说应该把它当成是鲜少用到的工具并直接忽略。
; 文档可以嵌套,有时关系型数据库涉及几个表的操作,在 MongoDB 中一次就能完成,可以减少昂贵的连接花销; 文档不对数据结构加以限制,不同的数据结构可以存储在同一张表; MongoDB 的文档数据模型和索引系统能有效提升数据库性能...x" : 1, "y" : 30 } 上述查找命令跳过 1 个文档,限制输出 10 个,以 age 子段正序排序(大于 0 为正序,小于 0 位反序)输出结果。...在实际工作中你很可能会用到ObjectId, 所以我们在这里也使用它) 显然,要找到Leto的所有员工,只要执行: db.employees.find({manager: ObjectId("4d85c7039ab0fd70a117d730...4.1.1 数组和嵌入文档(Embedded Documents) MongoDB 没有连接并不意味着它没有其他的优势。还记得我们曾说过 MongoDB 支持数组并把它当成文档中的一级对象吗?..."), ObjectId("4d85c7039ab0fd70a117d732")] }) 需要注意的是,在这种情况下,有些文档中的 manager 可能是一个向量,而其他的却是数组。
1 什么叫嵌入文档 如果从字面的意思理解,是一个文档中嵌套了或包含了另一个文档,这是一种关联数据的方式,利用这样的方式我们就直接避免了JOIN,对传统数据库的表的JOIN。...那么我们怎么办, 1建立一汽车零件表 2每种汽车有一个零件的数组,或者将各个部分的零件门类分类,然后将零件表里面的零件编号以数组的方式存储在另一个表里面。...ID数组(使用引用) ObjectId("..."), ObjectId("...") ], // 其他零件相关属性 } { "_id": ObjectId("..."),...ID数组(使用引用) ObjectId("..."), ObjectId("..."), ObjectId("...") // ......同时我们还可以注意到,引用可以双向引用,比如我通过零件也可以查到,这个零件用到那些车上,零件也可以自己来一个车辆的数组。 通过有效的索引设计,查询信息将非常快。
很多初学者认为在MongoDB中针对一对多建模唯一的方案就是在父文档中内嵌一个数组子文档,但是这是不准确的。因为你可以在MongoDB内嵌一个文档不代表你就必须这么做。...一对很少 一个人的地址为例,这时候使用内嵌文档是很合适,可以在person文档中嵌入数组地址文档: < db.person.findOne() { name: ‘Kate Monster’, ssn:...这个用例很适合使用间接引用-将零件的objectid作为数组存放在商品文档中(在这个例子中我使用更加易读的2字节的ObjectID,现实世界中他们可能是由12个字节组成的)。...我们可以使用很经典的处理方法“父级引用”—用一个文档存储主题,在每个日志文档中保存这个主机的ObjectID。..._id}).sort({time : -1}).limit(5000).toArray() 所以,即使这种简单的讨论也有能察觉出mongobd的建模和关系模型建模的不同之处。
2.文档查询 使用Spring Data来查询MongoDB的最常用方法之一是使用Query和Criteria类 , 它们非常接近本地操作符。..."_class" : "org.baeldung.model.User", "name" : "Alice", "age" : 35 } ] 下面是另一个简单的例子...,这里是Query和Criteria类的文档。...4.1 FindBy 让我们先从简单的,看看我们是如何将是一个通过查找类型的方法第一: @Query("{ 'name' : ?...0引用方法的第一个参数。 4.2 $regex 让我们来看一个正则表达式驱动的查询 - 这当然会产生与2.2和3.2相同的结果: @Query("{ 'name' : { $regex: ?
数据关系建模MongoDB中的数据关系建模方法包括嵌入式数据模型和引用式数据模型。嵌入式数据模型在嵌入式数据模型中,一个文档可以包含另一个文档。这种关系称为嵌入式关系。...下面是一个使用嵌入式数据模型的示例,其中一个订单文档包含了一组产品文档:{ "_id": ObjectId("615c24da614b1fde2c9ccdf1"), "orderNumber": "...“products”的嵌入式文档数组,其中每个嵌入式文档都代表一个产品。...引用式数据模型在引用式数据模型中,一个文档通过引用另一个文档来建立关系。这种关系称为引用式关系。引用式关系是MongoDB中另一种常用的关系类型。...下面是一个使用引用式数据模型的示例,其中一个订单文档包含了一个客户ID:{ "_id": ObjectId("615c24da614b1fde2c9ccdf1"), "orderNumber": "
文档中字段中的值可以包括其他文档,成为内嵌文档,也可以包括数组和文档数据 关于文档存储的优点有这些: 文档 即为对象,对应于许多编程语言中的本机数据类型 嵌入式文档和数组减少了对连接的需求 动态模式支持流畅的多态性...String 2 字符串,UTF-8才是合法的 Object 3 用于内嵌文档 Array 4 数组 Binary data 5 二进制数据 Udefined 6 “undefined” Objectid...}) 更新文档数据 db.collection.save({带有 Objectid 的数据}) 替换已有文档,若 Objectid 主键存在就更新,不存在就插入 db.collection.remove...子文档匹配 $regex 正则表达式匹配 关于 mongodb 查询的其他操作: 选择需要的字段 db.集合名字.find({},{字段名:1}) 排除不需要的字段 db.集合名字.find({},{...字段名:0}) 数组子元素的选择 db.集合名字.find({},{“字段名.子文档名的字段”:{$slice:[1,2]}) $slice ,可以取两个元素数组,分别表示跳过数和限制数 排序 sort
查询嵌套在数组中的文档 查询 instock 数组中包含 { warehouse: "A", qty: 5 } 的所有文档 > db.inventory.find( { "instock": {..."A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] } 在文档数组中嵌入的字段上指定查询条件 在 instock 数组中,至少有一个文档的 qty...,如果不知道文档的准确索引值,只能按照以下格式 数组字段名.文档字段名 instock.qty 使用数组索引查询嵌入文档中的字段 上面的栗子是直接根据字段名查找 在 instock 数组中,第一个元素包含字段...(当然同一个文档同时满足也可以) 只要整个文档数组中,两个条件都至少有一个满足的文档即可 栗子二 找到在 instock 数组中【至少有一个嵌入文档包含 qty = 5,以及至少有一个嵌入文档(但不一定是同一个嵌入文档...(前面讲数组的时候也提到过) 栗子一 找到在 instock 数组【至少有一个包含 qty = 5 和 warehouse = A 的嵌入文档 】的文档 > db.inventory.find( { "
mongoose.connect(uri,{keepAlive:120}) 五、models-模型 Models 是从 Schema 编译来的构造函数。...-SubDocuments 子文档是指嵌套在另一个文档中的文档。...Mongoose子文档有两种不同的概念:子文档数组和单个嵌套子文档 const chidlSchema = new Schema({name:String}) const parentSchema...= new Schema({ children:[childSchema], child:childSchema }) 子文档与文档的区别是 子文档不能单独保存,他们会在他们的顶级文档保存时保存...字段为 ObjectID 数组,ref 选项告诉mongoose 在填充的时候使用哪个 model,上面的例子就是指 Story 的 model。
2.4 查询 掌握选择器(Selector):MongoDB 的查询选择器就像 SQL 语句里面的 where 一样。 因此,你会在对集合的文档做查找,计数,更新,删除的时候用到它。...只能在我们的应用代码中自己实现,需要进行二次查询 find ,把相关数据保存到另一个集合中。...ObjectId( "4d85c7039ab0fd70a117d730")}); // 插入一个 manager 是 数组。...这要用到内嵌文档,比如 user: {id: ObjectId('Something'), name: 'Leto'}。缺点是,如果用户可以更新他们的名字,那将不得不对所有的文档都进行更新。...其他选择 记住: 一个独立文档的大小当前被限制在 16MB 。 处理一对多(one-to-many)或者多对多(many-to-many)场景的时候,id 数组通常是一个正确的选择。
22.85, 30 ] }, { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } ]); 后面的栗子都会用到这里的测试数据........ }} 实际栗子 查询数组 dim_cm 中至少包含一个值大于 25 的元素的所有文档 > db.inventory.find( { dim_cm: { $gt: 25 } } ) { "_id...使用 $elemMatch 运算符在数组元素上指定多个条件,使得至少一个数组元素满足所有指定条件 小栗子 查询 dim_cm 数组包含至少一个大于 (gt) 22 且小于 (lt) 30 的元素的文档...查询 dim_cm 数组第二个元素大于 25 的文档(索引位置从 0 开始哦) > db.inventory.find( { "dim_cm.1": { $gt: 25 } } ) { "_id" :...dim_cm" : [ 22.85, 30 ] } 按数组长度查询数组 查询包含长度= 3 的 tags 数组的文档 > db.inventory.find( { "tags": { $size: 3
这意味着,接下来的所有输入到MongoDB shell中的命令都将在library中执行,除非将该变量重置为另一个数据库。...而insertOne插入单条返回文档ID,insertMany插入多条返回多个文档ID构成的数组。 > document = ( { "Type" : "Book", ......这点在需要将查询的结果严格按照文档插入顺序时非常有用。 固定集合的大小固定。一旦固定集合达到设置的大小,最老的数据将被删除,最新的数据将被添加到末端,保证自然顺序与文档插入的顺序一致。...已经添加到固定集合的文档可以更新,但文档大小不能改变,否则更新将会失败。也不能从固定集合中删除文档。如果要删除文档,必须删除整个集合并重建。...这时将用到$natural参数。
2.算术运算符,如 MongoDB索引分类 _id默认的单字段唯一索引 单字段索引:建立在集合单一字段上的索引 复合索引:建立在集合多个字段上的索引 Multikey索引:如果一个字段是一个数组,在这个字段上面创建索引...地理空间索引:基于坐标平面查找的索引(使用场景较为特殊,暂不探讨) 文本索引:支持文档内的字符串查找 hash索引:Hash索引对key进行hash计算然后创建索引,该索引只支持等于查询,不支持区间查询...单字段索引 创建索引的api,3.0之后使用createIndex,ensureIndex已经废弃 * 对于单字段索引,排序的顺序是升序还是降序无关紧要 文档字段索引 db.records.createIndex...10 } } ) 子文档字段索引 db.people.createIndex( { "address.zipcode": 1 } ) 子文档索引 //示例数据 { _id: ObjectId(...db.factories.find( { metro: { city: "New York", state: "NY" } } ) //该查询不会用到子文档索引,因为子文档字段顺序不匹配 db.factories.find
最后5种带有星号的数据类型都不是JSON类型,它们是BSON中使用的特殊数据类型。 (3)在文档中内嵌或引用信息 可以选择在文档中内嵌信息,或者引用另一个文档中的信息。...内嵌信息意味着在文档自身中添加某种类型的数据,引用信息意味着创建对另一个包含了特定数据的文档的应用。...其本质就是用数据冗余替代表关联,MongoDB中所有的引用都将在数据库中产生另一个查询。 2. 构建索引 MongoDB中的索引是一种数据结构,用于收集集合中文档特定字段的值的信息。...要添加地理空间信息的文档必须含有一个子对象或数组(第一个元素指定对象类型,紧接着是该元素的经纬度),例如: > db.restaurants.insert({name:"Kimono",loc:{type...,需要指定一组包含了点坐标信息的嵌套数组。
最后,通过选项multi可以指定是否应该更新所有匹配的文档,或者只更新第一个文档(默认行为)。...通过这种方式可以限制$push操作符中数组内元素的数量。$slice接受负数或0。使用负数将保证数组中的最后n个元素会保留,而使用0则表示清空数组。...Author" : [ "Griffin, Meg", "Griffin, Louis" ] } > $addToSet 操作符$addToSet是另一个可用于向数组中添加数据的命令...使用Update if Current方法 另一个更新数据的策略是使用Update if Current(如果数据目前仍未改变就更新)方法。...还可以通过执行findAndModify命令来实现对文档的原子操作。该命令将修改并返回文档。
领取专属 10元无门槛券
手把手带您无忧上云