`
duwei118
  • 浏览: 3948 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

MongoDB:3. Schema Design

 
阅读更多
MongoDB:3. Schema Design

数据库正则表达式schemaschemadesignmongodb

摘要:1. Document-Oriented MongoDB 是一种面向文档(document-oriented)的数据库,其内存储的是一种 JSON-like 结构化数据。尽管拥有和关系型数据库 Database/Table 类似的的 DB/Collection 概念,但同一 Collection 内的
1. Document-Oriented
MongoDB 是一种面向文档(document-oriented)的数据库,其内存储的是一种 JSON-like 结构化数据。尽管拥有和关系型数据库 Database/Table 类似的的 DB/Collection 概念,但同一 Collection 内的 Document 可以拥有不同的属性。
(注: 以下 > 提示符表示 mongo JS 代码,>>> 为 Python 代码)
> use blog 
switched to db blog 

> db.users.insert({name:"user1", age:15}) 
> db.users.insert({name:"user2", age:20, sex:1}) 

> db.users.find() 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "age" : 15 } 
{ "_id" : ObjectId("4c479896089df9b53474170b"), "name" : "user2", "age" : 20, "sex" : 1 }
可以通过 $exists 判断某个字段是否存在。
> db.users.find({sex:{$exists:true}}) 
{ "_id" : ObjectId("4c479896089df9b53474170b"), "name" : "user2", "age" : 20, "sex" : 1 }
2. Embed vs. Reference
Document 采取 JSON-like 这种层级结构,因此我们可以直接用嵌入(Embed)代替传统关系型数据库的关联引用(Reference)。
> u = db.users.findOne({name:"user1"}) 

        "_id" : ObjectId("4c479885089df9b53474170a"), 
        "name" : "user1", 
        "age" : 15 


> u.address = ["address1", "address2"] 
[ "address1", "address2" ] 

> db.users.save(u) 

> db.users.findOne({name:"user1"}) 

        "_id" : ObjectId("4c479885089df9b53474170a"), 
        "name" : "user1", 
        "age" : 15, 
        "address" : [ 
                "address1", 
                "address2"
        ] 


> db.users.findOne({address:"address1"}) 

        "_id" : ObjectId("4c479885089df9b53474170a"), 
        "name" : "user1", 
        "age" : 15, 
        "address" : [ 
                "address1", 
                "address2"
        ] 
}
MongoDB 支持以 "." 分割的 namespace 路径,但需要注意 key 不能以 "$" 开头,不能包含 "." 字符 (条件表达式中的多级路径须用引号)。
> u = db.users.findOne({address:"address1"}) 

        "_id" : ObjectId("4c479885089df9b53474170a"), 
        "name" : "user1", 
        "age" : 15, 
        "address" : [ 
                "address1", 
                "address2"
        ] 


> u.im = {msn:"user1@hotmail.com", qq:12345678} 
{ "msn" : "user1@hotmail.com", "qq" : 12345678 } 

> db.users.save(u) 

> u = db.users.findOne({"im.qq":12345678}) 

        "_id" : ObjectId("4c479885089df9b53474170a"), 
        "name" : "user1", 
        "age" : 15, 
        "address" : [ 
                "address1", 
                "address2"
        ], 
        "im" : { 
                "msn" : "user1@hotmail.com", 
                "qq" : 12345678 
        } 


> u.im.qq 
12345678 

> u.im.msn 
user1@hotmail.com 

> db.users.update({"im.qq":12345678}, {$set:{"im.qq":12345}}) 

> u = db.users.findOne({"im.qq":12345}) 

        "_id" : ObjectId("4c479885089df9b53474170a"), 
        "name" : "user1", 
        "age" : 15, 
        "address" : [ 
                "address1", 
                "address2"
        ], 
        "im" : { 
                "msn" : "user1@hotmail.com", 
                "qq" : 12345 
        } 


> u = db.users.find({"im.qq":{$exists:true}}, {"im.qq":1}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "im" : { "qq" : 12345 } }
注意: 由于每篇文档都包含完整的 key 数据,因此使用尽可能短的 key 可以有效节省存储空间。
3. Operator
(1) $all: 判断数组属性是否包含全部条件。
> db.users.insert({name:"user3", data:[1,2,3,4,5,6,7]}) 
> db.users.insert({name:"user4", data:[1,2,3]}) 

> db.users.find({data:{$all:[2,3,4]}}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "name" : "user3", "data" : [ 1, 2, 3, 4, 5, 6, 7 ] }
注意和 $in 的区别。$in 是检查目标属性值是条件表达式中的一员,而 $all 则要求属性值包含全部条件元素。
(2) $size: 匹配数组属性元素数量。
> db.users.insert({name:"user3", data:[1,2,3,4,5,6,7]}) 
> db.users.insert({name:"user4", data:[1,2,3]}) 

> db.users.find({data:{$size:3}}) 
{ "_id" : ObjectId("4c47a13bb48cde79c6780df1"), "name" : "user4", "data" : [ 1, 2, 3 ] }
(3) $type: 判断属性类型。
> db.users.insert({name:"user5", t:1}) 
> db.users.insert({name:"user6", t:1.34}) 
> db.users.insert({name:"user7", t:"abc"}) 

> db.users.find({t:{$type:1}}) 
{ "_id" : ObjectId("4c47a231b48cde79c6780df2"), "name" : "user5", "t" : 1 } 
{ "_id" : ObjectId("4c47a23eb48cde79c6780df3"), "name" : "user6", "t" : 1.34 } 

> db.users.find({t:{$type:2}}) 
{ "_id" : ObjectId("4c47a258b48cde79c6780df4"), "name" : "user7", "t" : "abc" }
类型值:
•double:1
•string: 2
•object: 3
•array: 4
•binary data: 5
•object id: 7
•boolean: 8
•date: 9
•null: 10
•regular expression: 11
•javascript code: 13
•symbol: 14
•javascript code with scope: 15
•32-bit integer: 16
•timestamp: 17
•64-bit integer: 18
•min key: 255
•max key: 127
(4) 使用正则表达式进行查询。
> db.users.find({name:/user[135]/i}, {name:1}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1" } 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "name" : "user3" } 
{ "_id" : ObjectId("4c47a231b48cde79c6780df2"), "name" : "user5" }
>>> users = db.users.find({"name" : {"$regex" : r"(?i)user[135]"}}, ["name"]) 
>>> for u in users: print u 
... 
{u'_id': ObjectId('4c479885089df9b53474170a'), u'name': u'user1'} 
{u'_id': ObjectId('4c47a133b48cde79c6780df0'), u'name': u'user3'} 
{u'_id': ObjectId('4c47a231b48cde79c6780df2'), u'name': u'user5'}
正则表达式标记:
i: 忽略大小写。
m: 默认为单行处理,此标记表示多行。
x: 扩展。
(5) 数组属性元素值匹配。
> db.users.find({data:"abc"}) 
{ "_id" : ObjectId("4c47a481b48cde79c6780df5"), "name" : "user8", "data" : [ { "a" : 1, "b" : 10 }, 3, "abc" ] } 

> db.users.find({data:{$elemMatch:{a:1, b:{$gt:5}}}}) 
{ "_id" : ObjectId("4c47a481b48cde79c6780df5"), "name" : "user8", "data" : [ { "a" : 1, "b" : 10 }, 3, "abc" ] }
{data:"abc"} 仅简单匹配数组属性是否包含该元素。$elemMatch 则可以处理更复杂的元素查找条件。当然也可以写成如下方式。
> db.users.find({"data.a":1, "data.b":{$gt:5}}) 
{ "_id" : ObjectId("4c47a481b48cde79c6780df5"), "name" : "user8", "data" : [ { "a" : 1, "b" : 10 }, 3, "abc" ] }
还可以直接使用序号进行操作。
> db.users.find({"data.2":3}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "name" : "user3", "data" : [ 1, 2, 3, 4, 5, 6, 7 ] } 
{ "_id" : ObjectId("4c47a13bb48cde79c6780df1"), "name" : "user4", "data" : [ 1, 2, 3 ] }
(6) $not: 取反,表示返回条件不成立的文档。
似乎只能跟正则和 $mod 一起使用????
> u = db.users.find({name:{$not:/user3/}}, {name:1}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1" } 
{ "_id" : ObjectId("4c47a13bb48cde79c6780df1"), "name" : "user4" } 
{ "_id" : ObjectId("4c47a231b48cde79c6780df2"), "name" : "user5" } 
{ "_id" : ObjectId("4c47a23eb48cde79c6780df3"), "name" : "user6" } 
{ "_id" : ObjectId("4c47a258b48cde79c6780df4"), "name" : "user7" } 
{ "_id" : ObjectId("4c47a481b48cde79c6780df5"), "name" : "user8" } 
{ "_id" : ObjectId("4c479896089df9b53474170b"), "name" : "user2" }
(7) $unset: 和 $set 相反,表示移除文档属性。
> u = db.users.find({name:"user1"}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "age" : 15, "address" : [ "address1", "address2" ], "im" : { "msn" : "user1@hotmail.com", "qq" : 12345 } } 

> db.users.update({name:"user1"}, {$unset:{address:1, im:1}}) 

> u = db.users.find({name:"user1"}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "name" : "user1" }
(8) $push: 和 $ pushAll 都是向数组属性添加元素。
> u = db.users.find({name:"user1"}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "name" : "user1" } 

> db.users.update({name:"user1"}, {$push:{data:1}}) 

> u = db.users.find({name:"user1"}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "data" : [ 1 ], "name" : "user1" } 

> db.users.update({name:"user1"}, {$pushAll:{data:[2,3,4,5]}}) 

> u = db.users.find({name:"user1"}) 
{ "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "data" : [ 1, 2, 3, 4, 5 ], "name" : "user1" }
(9) $addToSet: 和 $push 类似,不过仅在该元素不存在时才添加 (Set 表示不重复元素集合)。
> db.users.update({name:"user2"}, {$addToSet:{data:1}}) 
> db.users.update({name:"user2"}, {$addToSet:{data:1}}) 

> u = db.users.find({name:"user2"}) 
{ "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1 ], "name" : "user2" } 
> db.users.update({name:"user2"}, {$push:{data:1}}) 

> u = db.users.find({name:"user2"}) 
{ "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1, 1 ], "name" : "user2" }
要添加多个元素,使用 $each。
> db.users.update({name:"user2"}, {$addToSet:{data:{$each:[1,2,3,4]}}}) 

> u = db.users.find({name:"user2"}) 
{ "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1, 2, 3, 4 ], "name" : "user2" }
(10) $pop: 移除数组属性的元素,$pull 按值移除,$pullAll 移除所有符合提交的元素。
> u = db.users.find({name:"user3"}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 1, 2, 3, 4, 5, 6, 7, 2, 3 ], "name" : "user3" } 

> db.users.update({name:"user3"}, {$pop:{data:1}}) // 移除最后一个元素 

> u = db.users.find({name:"user3"}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 1, 2, 3, 4, 5, 6, 7, 2 ], "name" : "user3" } 

> db.users.update({name:"user3"}, {$pop:{data:-1}}) // 移除第一个元素 

> u = db.users.find({name:"user3"}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 2, 3, 4, 5, 6, 7, 2 ], "name" : "user3" } 

> db.users.update({name:"user3"}, {$pull:{data:2}}) // 移除全部 2 

> u = db.users.find({name:"user3"}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 3, 4, 5, 6, 7 ], "name" : "user3" } 

> db.users.update({name:"user3"}, {$pullAll:{data:[4,5,6]}}) // 移除 4,5,6 

> u = db.users.find({name:"user3"}) 
{ "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 3, 7 ], "name" : "user3" }
(11) $where: 用 JS 代码来代替有些丑陋的 $lt、$gt。
MongoDB 内置了 Javascript Engine (SpiderMonkey)。可直接使用 JS Expression,甚至使用 JS Function 写更复杂的 Code Block。
> for (var i = 0; i < 10; i++) db.users.insert({name:"user"+i, age:i}) 

> db.users.find() 
{ "_id" : ObjectId("4c47b3372a9b2be866da226e"), "name" : "user0", "age" : 0 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da226f"), "name" : "user1", "age" : 1 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2270"), "name" : "user2", "age" : 2 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2271"), "name" : "user3", "age" : 3 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2272"), "name" : "user4", "age" : 4 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2273"), "name" : "user5", "age" : 5 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2274"), "name" : "user6", "age" : 6 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2275"), "name" : "user7", "age" : 7 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2276"), "name" : "user8", "age" : 8 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2277"), "name" : "user9", "age" : 9 } 

> db.users.find({$where:"this.age > 7 || this.age < 3"}) 
{ "_id" : ObjectId("4c47b3372a9b2be866da226e"), "name" : "user0", "age" : 0 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da226f"), "name" : "user1", "age" : 1 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2270"), "name" : "user2", "age" : 2 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2276"), "name" : "user8", "age" : 8 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2277"), "name" : "user9", "age" : 9 } 

> db.users.find("this.age > 7 || this.age < 3") 
{ "_id" : ObjectId("4c47b3372a9b2be866da226e"), "name" : "user0", "age" : 0 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da226f"), "name" : "user1", "age" : 1 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2270"), "name" : "user2", "age" : 2 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2276"), "name" : "user8", "age" : 8 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2277"), "name" : "user9", "age" : 9 } 

> db.users.find({$where: function(){ return this.age > 7 || this.age < 3;}}) 
{ "_id" : ObjectId("4c47b3372a9b2be866da226e"), "name" : "user0", "age" : 0 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da226f"), "name" : "user1", "age" : 1 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2270"), "name" : "user2", "age" : 2 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2276"), "name" : "user8", "age" : 8 } 
{ "_id" : ObjectId("4c47b3372a9b2be866da2277"), "name" : "user9", "age" : 9 }
>>> for u in db.users.find({"$where":"this.age > 7 || this.age < 3"}): print u 
... 
{u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'} 
{u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'} 
{u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'} 
{u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'} 
{u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'} 

>>> for u in db.users.find().where("this.age > 7 || this.age < 3"): print u 
... 
{u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'} 
{u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'} 
{u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'} 
{u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'} 
{u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'} 

>>> for u in db.users.find().where("function() { return this.age > 7 || this.age < 3;}"): print u 
... 
{u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'} 
{u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'} 
{u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'} 
{u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'} 
{u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}
分享到:
评论

相关推荐

    The.Little.Mongo.DB.Schema.Design.Book151739402

    The Little MongoDB Schema Design Book, covers the fundamentals off Schema design with MongoDB, as well as several useful Schema design patters for your applications. I wrote this book to be a helpful...

    MongoDB.Data.Modeling.1782175342

    Focus on data usage and better design schemas with the help of MongoDB About This Book Create reliable, scalable data models with MongoDB Optimize the schema design process to support applications of...

    mongodb-meetup-schema-design

    ### MongoDB Meetup Schema设计 #### 一、简介与原则 本次演讲由10gen的工程师Kyle Banker在2010年9月21日的MongoNYC会议上进行。主要内容涵盖了MongoDB的基本介绍、设计原则以及如何在MongoDB中进行有效的模式...

    mongodb_架构设计基础schemadesign-cn

    从给定的文件信息中,我们可以提炼出关于MongoDB架构设计基础的重要知识点,涉及数据建模的历史、目的、以及在MongoDB中实现这些设计的具体方法。 ### 数据建模简史 数据建模的历史源远流长,从最早的ISAM...

    MongoDB in Action, 2nd Edition

    Application developers love MongoDB, a document-... A reference section on schema design patterns helps ease the transition from the relational data model of SQL to MongoDB’s document-based data model.

    mongodb-schema-simulator:了解MongoDB Hardway代码和其他相关内容

    构建MongoDB Schema Simulator Tool的目的是允许模拟《 The Little MongoDB Schema Design Book概述的The Little MongoDB Schema Design Book 。 链接 安装工具 安装该工具非常简单 npm install -g mongodb-schema-...

    mongodb-schema-design:JSON模式定义,用于灵活的广告分类引擎

    "mongodb-schema-design"项目专注于JSON模式定义,为构建一个灵活的广告分类引擎提供了数据模型的指导。 JSON(JavaScript Object Notation)模式定义在MongoDB中起到了类似传统关系数据库中的表结构的作用,但它...

    50 Tips and Tricks for MongoDB Developers

    Application Design Tips: What to keep in mind when designing your schema Implementation Tips: Programming applications against MongoDB Optimization Tips: Speeding up your applications Data Safety Tips...

    Flask By Example.pdf 最新 原版

    - Enhancing user interaction through responsive design. 5. **Advanced Topics and Best Practices**: - Deploying Flask applications to production environments. - Debugging and testing strategies. -...

    项目-博客。

    3. **MongoDB数据库**:由于“node项目-博客”的标签没有提及特定的数据库,但考虑到Node.js社区的常见选择,项目可能使用了NoSQL数据库MongoDB。MongoDB是一个文档型数据库,适合存储结构灵活的数据,如JSON格式,...

    SafeAuth:使用React&Express创建的安全loginregister应用程序

    在SafeAuth后端,Mongoose为我们定义了用户模型(User Schema),方便地进行数据操作,如创建新用户、查询用户信息等。 ### 六、环境配置与安全实践 在后端,`.env`文件用于存储敏感信息,如数据库连接字符串,...

    Chili-TV_api:辣椒tv服务器端:基于hapi

    这个项目是无聊的时候做的,主要客户端为移动端,利用唤醒URL schema原理, 可以将自己喜欢的资源通过百度云分享上传到平台 利用平台的共享性 或许自己的所需资源,相当于一个百度云盘的集合,整体项目分三部分 采用...

Global site tag (gtag.js) - Google Analytics