美文网首页
MongoDB的基本使用

MongoDB的基本使用

作者: 艾胖胖胖 | 来源:发表于2018-10-24 16:40 被阅读0次

一、MongoDB的简介

  • 概述
    MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

    MongoDB介于关系型数据和非关系型数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,类似json格式,因此可以存储比较复杂的数据类型。

    MongoDB最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库表单查询的绝大部分功能,而且还支持对数据建立索引。

  • 特点
    非关系型数据库(nosql ),属于文档型数据库。存储方式:虚拟内存+持久化。
    查询语句:是独特的MongoDB的查询方式。
    适合场景:事件的记录,内容管理或者博客平台等等。
    数据处理:数据是存储在硬盘上的,只不过需要经常读取的数据会被加载到内存中,将数据存储在物理内存中,从而达到高速读写。
    成熟度与广泛度:新兴数据库,成熟度较低,Nosql数据库中最为接近关系型数据库,比较完善的DB之一,适用人群不断在增长。
    优势: 快速!在适量级的内存的MongoDB的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据的读写变得十分快, 高扩展, json的存储格式!

  • 关系型数据库和非关系型数据库的区别
    关系型数据库通过外键关联来建立表与表之间的关系。

    非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定。

    学生: 张三
    性别: 男
    科目: 语文
    成绩: 80
    
    关系型数据库:
      // 学生表
      create table student(id int primary key, name char(50), sex char(10))
     // 成绩表,stuid存储的是学生表中对应的主键,用于表的关联
      create table score(id int primary key, name char(20),grade int,stuid int, foreign key(stuid) references student(id))
    
    非关系型数据库:
    {
      "name":"张三",
      "sex":"男",
      "score":{
        "name":"语文",
        "grade": 80
      }
    }
    

常见关系型数据库SQLite、Oracle、MySQL、SQLServer
常见非关系型数据库 MongoDB、Redis

MongoDB的安装

  • Windows的安装
- 官网下载地址:https://www.mongodb.com/download-center/community

- 安装

- 创建数据目录
  MongoDB将数据目录存储在 db 目录下。但是这个数据目录不会主动创建,我们在安装完成后需要创建它。请注意,数据目录应该放在根目录下((如: C:\ 或者 D:\ 等 )。

- 命令行下运行 MongoDB 服务器
  C:\mongodb\bin\> mongod --dbpath c:\data\db(数据目录)

  • Ubuntu的安装
第1步 – 导入公钥**
  //Ubuntu软件包管理器apt(高级软件包工具)需要软件分销商的GPG密钥来确保软件包的一致性和真实性。 执行此下面的命令将MongoDB密钥导入到您的服务器:
  sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5

第2步 – 创建源列表文件MongoDB
  检查URL http://repo.mongodb.org/apt/ubuntu/dists/。
  如果您在该网页上看到一个目录“bionic”,则将下述命令中的单词“xenial”替换为“bionic”一词,
【原因:MongoDB尚未发布Bionic Beaver软件包,但Xenial软件包在Ubuntu 18.04 LTS上运行良好】
  执行以下命令在/etc/apt/sources.list.d/中创建一个MongoDB列表文件:
  echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list

第3步 – 更新存储库
  使用apt命令更新存储库:
  sudo apt-get update
  说明:执行完会提示一些失败,不用在意

第4步 – 安装MongoDB
  执行以下命令来安装MongoDB:
  sudo apt-get install -y mongodb

第5步:启动MongoDB
  执行以下命令启动MongoDB并将其添加为在启动时启动的服务
  sudo systemctl start mongodb

    如果执行完这一步终端没有任何输出,则说明是正确的
    如果启动的时候提示:Failed to start mongod.service: Unit mongodb.service not found.
    解决办法如下:
    1.创建配置文件:
      cd /etc/systemd/system/
      sudo vi mongodb.service
    2.在里面追加文本:
      [Unit]
      Description=High-performance, schema-free document-oriented database
      After=network.target
      [Service]
      User=mongodb
      ExecStart=/usr/bin/mongod --quiet --config /etc/mongodb.conf
      [Install]
      WantedBy=multi-user.target
    3.退出
      :wq
    4.启动服务
      sudo systemctl start mongodb
      sudo systemctl status mongodb
    5.设置开机自启动
      sudo systemctl enable mongodb

第6步:登录MongoDB
      mongo
      如果出现错误全局初始化失败:BadValue无效或无用户区域设置。 请确保LANG和/或LC_ *环境变量设置正确,请尝试命令:
      export LC_ALL=C

备注: 默认MongoDB是绑定127.0.0.1,连接远程是连接不了的。
编辑MongoDB配置文件: sudo vi /etc/mongodb.conf
找到 bind_ip = 127.0.0.1 改为 bind_ip = 0.0.0.0

三、MongoDB的可视化管理工具

  • Robo 3T或Studio 3T
// Robo 3T免费, Studio 3T收费
 下载地址:https://robomongo.org/

四、MongoDB之数据库的操作

  • 创建数据库
> show dbs 查看当前都有哪些数据库

> use DATABASE_NAME  创建数据库
注意:如果DATABASE_NAME不存在,则该命令将创建一个新的数据库,否则选择该数据库
> db.dropDatabase()  删除数据库
注意:默认删除当前正在工作的数据库

admin:从权限的角度来说,是root的数据库
​ local:本地数据
​ config:配置,用于保存MongoDB的配置信息

  • 集合

- 集合名的规范:
  a.不能空字符串
  b.集合名不能含有\0【空字符】,表示集合名的结尾
  c.集合名不能以"system."开头,为系统集合保留的关键字
  d.不能含有保留字符,千万不能含有$

- 查看当前数据库中的集合:
  show collections

- 创建集合:
  db.createCollection(name, options)
  // name的类型为String,是要创建的集合的名称
  // options的类型是Document,是一个文档,指定相应的大小和索引,是可选参数
  // 在插入文档时,MongoDB首先检查上限集合capped字段的大小,然后检查max字段
  例如:
  db.createCollection("mycol",{capped:true,autoIndexId:true,size:1024,max:10000})

- 删除集合
 // 如果选定的集合成功删除,drop()方法将返回true,否则返回false
  db.COLLECTION_NAME.drop()
  例如:
  db.mycollection.drop()

五、MongoDB的文档操作

  • 文档概念
    文档:相当表中的一条记录【实体】是一组键值对,文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型

a.文档中的键值对是有序的
b.文档中值除了字符串之外,还可以是其他数据类型【嵌套一个文档】
c.严格区分大小写和数据类型的,mycol myCol
d.文档中不能有重复的键
e.文档中的键基本都是用字符串表示的

  • 文档的命名规范

a.键不能包含\0
b.$和.有特殊含义
c.以下划线开头的键是保留的,尽量不要使用下划线开头

  • 文档的插入
语法:
  // 在插入的文档中,如果不指定_id参数,那么 MongoDB 会为此文档分配一个唯一的ObjectId
  // _id为集合中的每个文档唯一的12个字节的十六进制数。
  db.COLLECTION_NAME.insert(document)

例如:
  // 插入一个
  db.mycol.insert({id:101, name:'lisi', age:20})
  db.mycol.insert({ 
     item: "canvas", 
     num: 100, 
     tags: ["cotton"], 
     size: { 
          h: 20,
          w: 30, 
      } 
  })

  // 插入多个(注意方括号)
  db.mycol.insert( [{id:102, name:'wagnwu', age:18}, {id:103, name:'zhaoliu', age:21}, {id:104, name:'tianqi', age:19}] )
  

  // 查看已插入的文档
  db.mycol.find()
  { "_id" : ObjectId("5b8b59cb5bd1df1fc73dcdc6"), "id" : 101, "name" : "lisi", "age" : 20 }

  // 查看已插入的文档
  db.mycol.find().pretty()
  {
  "_id" : ObjectId("5b8b59cb5bd1df1fc73dcdc6"),
  "id" : 101,
  "name" : "lisi",
  "age" : 20
  }

  • 文档的基础查询
语法:
  // 基本操作
  db.COLLECTION_NAME.find(document)
   // 以格式化的方式返回查询结果
   db.COLLECTION_NAME.find(document).pretty()
   

注意: 
  find() 将以非结构化的方式返回查询结果
 
 例如: 
  // 显示所有文档
  db.mycol.find()
  
  // 默认将所有文档显示,为了限制列表,需要显示的字段设置为1,不显示的设置为0
  db.mycol.find( {'name':'liming'}, {'name':1, 'age': 1} )
  db.mycol.find( {'name':'liming'}, {'age':0} )
  
  // 限制字段显示
  db.check.find({},{'_id':1,'title':1})

  • 文档的条件查询
- 等于{ <key>:<value> }
  db.mycol.find({'name':'zyz'} ).pretty()

- 小于 { <key>: {$lt:<value>} }
  db.mycol.find( {'age': {$lt:18}} ).pretty()

- 小于等于 { <key>: {$lte:<value>} }
  db.mycol.find( {'age': {$lte:18}} ).pretty()

- 大于 { <key>: {$gt:<value>} }
  db.mycol.find( {'age': {$gt:18}} ).pretty()

- 大于等于 { <key>: {$gte:<value>} }
  db.mycol.find( {'age': {$gte:18}} ).pretty()

- 不等于 { <key>: {$ne:<value>} }
  db.mycol.find( {'age': {$ne:18}} ).pretty()

- 并列关系(and)
  在find()方法中,如果通过使用 ',' 将它们分开传递多个键,则 MongoDB 将其视为AND条件
  db.mycol.find(
    {
      $and: [
        {key1: value1}, {key2: value2}
      ]
    }
  )

- 或者关系(or)
  db.mycol.find(
    {
      $or: [
        {key1: value1}, {key2: value2}
      ]
    }
  )

  • 文档的更新
update()更新现有文档中的值,语法:
  db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)
例如:
  // update默认只更新一个文档,如果要更新多个文档,则添加参数{multi:true})
  db.check.update( {'title': 'MongoDB Guide'}, {$set: {'title': 'mongo'}} )
  db.check.update( {'title': 'MongoDB Guide'}, {$set: {'title': 'mongo'}, $set: {'say': 'hello'}} )
  db.check.update( {'title': 'MongoDB Guide'}, {$set: {'title': 'mongo'}}, {multi: true} )

save()用传递的文档数据替换现有文档,语法:  
  db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA})
例如:
  db.check.save( {'_id':102, 'title':'hello', 'by':'lalala'} )

  • 删除文档
语法:
  db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)

 例如:
   db.check.remove( {'_id':100} )

六、MongoDB之查询

  • 投影
    查询过程中,只显示指定的字段
语法:
  db.COLLECTION_NAME.find({},{KEY:1})

例如:
  db.mycol.find( {}, {'title':1, _id:0} )

在执行find()方法时,始终都会显示_id字段,如果不想要此字段,则需要将其设置为0

  • 限制筛选记录
limit()限制MongoDB要返回的记录数,根据指定的参数返回记录数
语法:
  db.COLLECTION_NAME.find().limit(NUMBER)
例如: 
  // 在查询文档时仅显示两个文档
  db.mycol.find({},{"title":1,_id:0}).limit(2)

skip() 方法跳过指定数量的数据
语法:
  // 注意:skip()方法中的默认值为0。
  db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
例如:
  db.mycol.find({},{"title":1,_id:0}).limit(1).skip(2)

  • 对查询记录排序
语法:
    // 使用指定顺序进行排序,1表示升序,-1表示降序
    db.COLLECTION_NAME.find().sort({KEY:1})
  例如:
     db.mycol.find({},{"title":1,_id:0}).sort({"title":-1})
  • 管道的概念
    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档
  db.article.aggregate( [ {$project:{by_user:1, title:1}} ] )

$limit:用来限制MongoDB聚合管道返回的文档数
  db.article.aggregate( [ {$project:{by_user:1, title:1}}, {$limit: 2} ] )  

$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档
  db.article.aggregate( [ {$project:{by_user:1, title:1}}, {$skip: 1} ] )
  db.article.aggregate( [ {$project:{by_user:1, title:1}}, {$limit:2},{$skip: 1} ] ) 

$group:将集合中的文档分组,可用于统计结果
  db.article.aggregate( [ {$group: {_id:'$by_user', num:{$sum:'$likes'}}} ] )

$sort:将输入文档排序后输出
  db.article.aggregate( [ {$group: {_id:'$by_user', num:{$sum:'$likes'}}},{$sort: {'num':-1}} ] )

  • 分组与聚合函数查询
aggregate()语法:
  db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

- $sum 从集合中的所有文档中求出定义的值
  // 计算每个作者所写的文章点赞数
  db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
  // 计算每个作者所写文档数量
  // select by_user, count(*) from article group by by_user
  db.article.aggregate([ { $group: {_id:'$by_user', num:{$sum:1}} } ])

- $avg 计算集合中所有文档的所有给定值的平均值
  db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])

- $max 从集合中的所有文档获取相应值的最大值
  // _id:'$by_user',对应按照by_user分组
  db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
  // _id对应一个常量,即所有数据的操作
  db.article.aggregate([ { $group:{_id:'max', num_likes:{$max:'$likes'}} } ])

- $min 从集合中的所有文档获取相应值的最小值
  db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])

- 例如:
  db.article.aggregate([{$group:{'_id':'$by_user','num_tutorial':{$sum:1}}}])

七、MongoDB之关联关系

MongoDB中的关系表示各个文档在逻辑上的相互关联。关系可以通过嵌入式和引用方法建模。 这种关系可以是1:1,1:N,N:1或N:N。

假设有一种情况:要存储用户的地址。一个用户可以拥有多个地址,这就是1:N关系。

// 用户user文档
{
   "_id":10999110,
   "name": "Maxsu",
   "contact": "13800138000",
   "dob": "1992-10-11"
}

// 地址文档
{
   "_id":12200,
   "building": "Hainan Building NO.2100",
   "pincode": 571100,
   "city": "Haikou",
   "province": "Hainan"
}

嵌入式关系建模
在嵌入式方法中,我们将地址(address)文档嵌入到用户(user)文档中

{
   "_id": 21000100,
   "contact": "13800138000",
   "dob": "1991-11-11",
   "name": "Maxsu",
   "address": [
      {
         "building": "Hainan Building NO.2100",
         "pincode": 571100,
         "city": "Haikou",
         "province": "Hainan"
      },
      {
         "building": "Sanya Building NO.2100",
         "pincode": 572200,
         "city": "Sanya",
         "province": "Hainan"
      },
   ]
}

该方法将所有相关数据保存在单个文档中,这使得检索和维护更容易。
可以使用单个查询来在整个文档检索:
 db.users.find( {"name":"Maxsu"},{"address":1, "name":1} )

在上述查询中,db和users分别是数据库和集合。缺点是如果嵌入式文档的大小如果不断增长,可能会影响读/写性能。

建模参考关系
这是设计规范化关系的方法。 
在这种方法中,用户和地址文件将分别维护,但用户文档将包含一个将引用地址文档的id字段的字段。
{
   "_id":ObjectId("52ffc33321332111sdfaf"),
   "contact": "13800138000",
   "dob": "1991-11-11",
   "name": "Maxsu",
   "address_ids": [
      ObjectId("123123"),
      ObjectId("123412")
   ]
}
用户文档包含对应地址的ObjectId的数组字段address_ids。 
使用这些ObjectIds,我们可以从那里查询地址文件并获取地址详细信息。 
使用这种方法,需要两个查询:首先从用户文档获取address_ids字段,然后从地址集中获取这些地址。
var result = db.users.find({"name":"Maxsu"},{"address_ids":1})
var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})

八、MongoDB与Python的交互

- 安装
pip3 install pymongo

- 使用
import pymongo
from pymongo import  MongoClient
from bson.objectid import ObjectId

#1.建立连接
#创建MongoClient的对象
#方式一
#特点:可以连接默认的主机和端口号
#client = MongoClient()
#方式二
#明确指明主机和端口号
#client = MongoClient('localhost',27017)
#client = MongoClient(host='localhost',port=27017)
#方式三
#使用MongoDB URI的
client = MongoClient('mongodb://localhost:27017')

#2.获取数据库
#MongoDB的一个实例可以支持多个独立的数据库
#可以通过MongoClient的对象的属性来访问数据库
#方式一
db = client.test
print(db)
#方式二
#db = client['test']


#3.获取集合
#集合是存储在MongoDb中的一组文档,可以类似于MySQl中的表
#方式一
collection = db.stuents
#方式二
#collection = db['students']
"""
注意:
MongoDB中关于数据库和集合的创建都是懒创建
以上的操作在MongoDB的服务端没有做任何操作
当第一个文档被插入集合的时候才会创建数据库和集合
"""

#4.文档
#在pymongo中使用字典来表示文档
student1 = {
    'id':'20180101',
    'name':'jack',
    'age':20,
    'gender':'male'
}

#5.插入文档
#5.1insert()
#插入单条数据
#注意:MongoDb会自动生成一个ObjectId,insert函数的返回值为objectid
result = collection.insert(student1)
print(result)


#插入多条数据
student2 = {
    'id':'20180530',
    'name':'tom',
    'age':30,
    'gender':'male'
}
student3 = {
    'id':'20180101',
    'name':'bob',
    'age':18,
    'gender':'male'
}
#result = collection.insert([student2,student3])

#6.查询文档
#6.1
#find_one()
result = collection.find_one({'name':'jack'})
print(type(result))    #<class 'dict'>
print(result)

#6.2find()
#需求:查询年龄为20的数据
results = collection.find({'age':20})
print(results)
#Cursor相当于是一个生成器,只能通过遍历的方式获取其中的数据
for r in results:
    print(r)

#6.3其他用法
#a.count()
#统计所有数据的条数
count1 = collection.find().count()
#统计制定条件的数据条数
count1 = collection.find({'age':20}).count()

#7.更新文档
#7.1update()
conditon = {'name':'jack'}
student = collection.find_one(conditon);
student['age'] = 30
result = collection.update(conditon,student)

#7.2update_one()
conditon = {'name':'jack'}
student = collection.find_one(conditon);
student['age'] = 30
result = collection.update_one(conditon,{'$set':student})
print(result.matched_count,result.modified_count)

#7.3update_many()
#查询年龄大于20的数据,然后讲年龄增加1
conditon = {'age':{'$gt':20}}
result = collection.update_one(conditon,{'$inc':{'age':1}})
print(result.matched_count,result.modified_count)

#8.删除文档
#8.1remove()
#将符合条件的所有的数据全部删除
result = collection.remove({'name':'rose'})

#8.2delete_one()
result = collection.delete_one({'name':'rose'})

#8.3delete_many()
result = collection.delete_many({'name':'rose'})

相关文章

  • Mongodb 02-CURD

    ===========mongodb =========== mongodb的基本使用 案列需求 存放文章评论的数...

  • MongoDB基本使用

    数据写入与查询 数据更新 数据删除 创建索引

  • MongoDB基本使用

    本文不想文绉绉的去分析MongoDB内部的数据存储结构,只是想单纯的从用的方面给大家一些指导,也不能说是指导,也是...

  • Mongodb基本使用

    启动服务:./bin/mongodb-3.2.10/bin/mongod -f conf/mongod.conf ...

  • Mongodb 基本使用

    例如:现在有数据库 ·

  • mongoDB 基本使用

    数据库帐号的创建与使用 参考不知博客官方说明 数据的备份还原 数据导入与导出 数据导出 注意: 导出类型为json...

  • MongoDB基本使用

    MongoDB基本概念 数据库(database) 数据库是一个仓库,在仓库中存放集合。 集合(collectio...

  • MongoDB基本使用

    成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作。 输入help可以看到基...

  • mongodb基本使用

    mongodb MongoDB是专为可扩展性,高性能和高可用性而设计的数据库。它可以从单服务器部署扩展到大型、复杂...

  • MongoDB的基本使用

    一、MongoDB的简介 概述MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。旨在为WEB应用提...

网友评论

      本文标题:MongoDB的基本使用

      本文链接:https://www.haomeiwen.com/subject/jsfxtqtx.html