`
duwei118
  • 浏览: 3719 次
  • 性别: 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-design\mongodb-meetup-schema-design\mongodb-meetup-schema-design

    50_tips_and_tricks_for_mongodb_developers.pdf

    Getting started with MongoDB is easy, but once you’re building applications with it more complex questions emerge....up everywhere, from schema design to implementation to data safety.

    mongodb_架构设计基础schemadesign-cn

    mongodb_架构设计基础schemadesign-cn

    MongoDB The Definitive Guide 3rd Edition

    Manage your data in a database system designed to support modern ... Ideal for NoSQL newcomers and experienced MongoDB users alike, this book also includes many real-world schema design examples.

    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数据模型。 贡献 欢迎通过贡献来改进数据模型,或者通过留下您的反馈。

    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...

    MongoDB权威指南 2nd

    Ideal for NoSQL newcomers and experienced MongoDB users alike, this guide provides numerous real-world schema design examples. Get started with MongoDB core concepts and vocabulary Perform basic ...

    MongoDB in Action

    Schema design patterns Deploying for scale and high availability ========================================​========== Table of Contents PART 1 GETTING STARTED A database for the modern web MongoDB...

    MongoDB Applied Design Patterns

    结合实例,介绍使用mongo和如何建立schema.很好的从入门到精通的书.

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

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

Global site tag (gtag.js) - Google Analytics