3

【MongoDB】部署,集合、文档、索引的基本操作

 2 years ago
source link: https://segmentfault.com/a/1190000040677755
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

MongDB入门

官网下载地址

  1. 数据库、集合、文档的基本操作

1 单机部署

  1. 下载、解压、配置
  2. 启动数据库
  3. 连接数据库

1.1 Windows下启动

下载后解压至本地
在解压后文件里创建一个目录用于存储数据文件 data/db

方式1:命令行参数方式启动服务

在bin目录中执行如下命令:

mongod --dbpath=..\data\db

默认端口27017,可以通过port指定端口

可以将bin目录设置到环境变量path中,方便使用一些命令

方式2:配置文件方式启动服务
新建config文件夹,在文件夹下新建配置文件mongod.config

storage:
  #The directory where the mongod instance stores its data.Default Value is "\data\db" on Windows.
  dbPath: F:\mongodb-5.0.2\data\db

在bin下执行

mongod -f ../config/mongod.config
或
mongod --config ../config/mogod.config

默认端口27017
在部署项目时,使用这种方法,有详细的参数

1.2连接数据库

1.2.1 Shell连接(mongo命令)

在bin下新打开一个shell窗口
连接

mongo
或
mongo --host=localhost --port=27017

查已有数据库

>show databases

退出mongodb

exit
mongo --help

MongoDB javascript shell 是一个基于JavaScript的解释器,支持js程序

1.2.2 Compass图形化界面的使用

下载地址选择社区版
填入ip与端口号 直接连接即可

1.3 Linux下启动与连接数据库

将下载的linux版本的MongoDB拷贝到服务器

  1. 下载、解压、移动

    sudo su
    sudo yum install libcurl openssl
    wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.2.tgz
    tar -xvf mongodb-linux-x86_64-rhel70-5.0.2.tgz
    mv mongodb-linux-x86_64-rhel70-5.0.2 /usr/local/mongodb
  2. 新建目录,存储数据和日志

    #数据存储
    mkdir -p /mongodb/single/data/db
    #日志存储
    mkdir -p /momgodb/single/log
  3. 新建配置文件

    vi /mongodb/single/mongod.config
  • systemLog:
    #MongoDB发送所有日志输出的目标指定文件
    ##The path of the log file to which mongod or mongos should send all diagnostic logging information
    destination: file
    #mongo或mongos应向发送所有诊断日志记录信息的日志文件路径
    path: "/mongodb/single/log/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
    logAppend: true
    storage:
    #mongod实例存储数据的目录 storage.dbPath设置仅使用于mongd
    ##The directory where the mongod instance stores its data.Default Value is "/data/db".
    dbPath: "/mongodb/single/data/db"
    journal:
      #启用或禁止持久性日志以确保数据文件保持有效和可恢复
      enabled: true
    processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式
    fork: true
    net:
    #服务实例绑定的IP,默认是localhost
    bindIp: localhost,172.19.18.168
    #bindIP局域网IP - ifconfig
    #绑定端口,默认为27017
    port: 27017
    #数据库路径
    dbpath=/mongodb/single/data/db
    
    #日志输出文件路径
    logpath=/mongodb/single/log/mongod.log
    
    #错误日志采用追加模式
    logappend=true
    
    #启用日志文件,默认启用
    journal=true
    
    #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
    quiet=true
    
    #端口号 默认为27017
    port=27017
    
    #允许远程访问(服务器局域网ip 用ifconfig检查)
    bind_ip=localhost,172.19.18.168
    
    #开启子进程
    fork=true
    
    #开启认证,必选先添加用户,先不开启(不用验证账号密码)
    #auth=true
  1. 启动MongoDB服务

    #启动
    /usr/local/mongodb/bin/mongod -f /mongodb/single/mongod.config
    或
    export PATH=/usr/local/mongodb/bin:$PATH
    mongod -f /mongodb/single/mongod.config
    #设置密码
    mongo
    use admin
    db.createUser({user:"root",pwd:"password",roles:["root"]})
    db.auth('root','password')

    可以将export PATH=/usr/local/mongodb/bin:$PATH添加到/etc/profile文件中
    这样不用每次都设置环境变量

    vim /etc/profile
    添加在export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL之后

    设置密码需要在配置中添加 auth = true

  • 通过进程来查看服务是否启动

    ps -ef |grep mongod
  1. Compass连接服务

    host:公网IP
    端口:27017

    防火墙开启与关闭

    #查看防火墙转态
    systemctl status firewalld
    #临时关闭防火墙
    systemctl stop firewalld
    #开启防火墙
    systemctl start firewalld
    #开机禁止启动防火墙
    systemctl disable firewalld
    #开机启用防火墙
    systemctl enable firewalld

    添加防火墙端口

    #开放端口
    firewall-cmd --zone=public --add-port=27017/tcp --permanent 
    #防火墙重新加载配置
    firewall-cmd --reload
    #查询开放的端口
    firewall-cmd --list-port
    #关闭一个防火墙端口
    firewall-cmd --zone=public --remove-port=27017/tcp --permanent
    #方式1
    kill -2 进程号
    #方式2
    pkill mongod
  • 可能出现的问题
    启动失败:一般就是配置文件的路径或者缺少必要的配置项,或者是启动命令错误
    连接失败:如果是云服务器,先检查防火墙规则或安全组是否放行27017端口,这里可以不在shell中操作,直接手动添加。检查配置文件的bindIp,修改为0.0.0.0,或者在localhost后添加内网ip
#本地cmd连接服务器数据库
mongodb/din] mongo --host=外网IP

2 基本常用命令

  1. 数据库的选择、创建、删除
  2. 集合的创建与删除
  3. 文档的CRUD

2.1 数据库操作

2.1.1 选择和创建数据库

#查看有权查看的所有数据库
> show dbs
> show datadases
#选择或创建一个数据库
> use dbname
  • use dbname,dbname存在时则选择进入该数据库,不存在时创建数据库并进入
  • 默认进入的数据库为test

2.1.2 数据库的删除

#查看当前数据库
> db
#删除当前数据库
> db.dropDatabase()
  • db表示当前数据库,可视为一个对象,上面有很多方法

admin: root,添加一个用户到此数据库,该用户自动继承所有数据库权限。一些特定服务器命令只能从这个数据库运行 - 列出所有数据库或关闭服务器
local:该数据库永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息

2.2集合操作

2.2.1集合的显示创建

#显式创建集合 - 关系数据库中的表
db.createCollection(name)
#查看集合
show collections

2.2.2集合的隐式创建

向一个集合插入一个文档的时候,如果集合不存在,则会自动创建集合

推荐使用此方法隐式创建文档

2.2.3 删除一个集合

#删除集合
db.collectionName.drop()
#查看
show collections

2.3 文档基本CRUD

2.3.1 文档的插入

  1. 单文档插入
    使用insert()save()方法向集合插入文档

    db.collectionName.insert(
     <document or array of document>,
     {
         writeConcern: <document>,
         ordered: <boolean>
     }
    )
    • document 要插入到集合的文档或文档数组(json格式)
    • writeConern 性能与可靠性的级别
    • ordered 插入时是否排序
    //示例
    db.comment.insert(
     {
         "articleid":"100",
         "content":"针不戳",
         "useid":"10",
         "nickname":"Jack",
         "creatdatetiem":new Date(),
         "likenum":NumberInt(10),
         "state":null
     }
    )
  2. 批量插入
    使用inserMany()

    db.collectionName.insertMany(
     [<document1> , <document2> , ...],
     {
         writeConern:<document>,
         ordered:<boolean>
     }
    )
    //示例
    db.comment.insertMany([
     {
         "articleid":"100",
         "content":"针不戳",
         "useid":"10",
         "nickname":"Jack",
         "creatdatetiem":new Date(),
         "likenum":NumberInt(10),
         "state":null
     },
     {
         "articleid":"100",
         "content":"这垃圾袋挺能藏啊",
         "useid":"1",
         "nickname":"pig",
         "creatdatetiem":new Date(),
         "likenum":NumberInt(1000),
         "state":null
     }
    ])

2.3.2 文档的基本查询

使用find()

db.collectionName.find(<query>,[projection])
  • query:可选,使用查询运算符指定筛选范围
  • projection:可选,指定要在与查询筛选器匹配的文档中返回的字段
#全部查询
db.comment.find()
#条件查询
db.comment.find({"useid":"10"})
#单文档条件查询
db.comment.findOne({"useid":"10"})
#投影查询
db.comment.find({"useid":"10"},{"useid":1,"_id":0})
  • 投影查询第一个参数为条件,第二个参数为要显示的数据

插入错误处理,将操作写在try中,catch捕获错误并print

2.3.3 文档的更新

使用update()

db.collectionName.update(query,update,options)
db.collectionName(
    <query>,
    <update>,
    {
        upsert:<boolean>,
        nulti:<boolean>,
        writeConcern:<document>,
        collation:<document>,
        arrayFilters:[<filterdocument1>,...],
        hint:<document|string>  //MondoDB 4.2
     }
)
#覆盖的修改 - 只保留更新的数据
db.comment.update(useid:"1",{content:"叫学姐"})
#局部的修改 - $set
db.comment.update({useid:"10"},{$set:{content:"学姐再见"}})
#批量修改 - multi:true修改所有符合条件的数据
db.comment.update({useid:"10"},{$set:{content:"学姐再见"}},{multi:true})
#列值增长的修改 - $inc
db.comment.update({useid:"10"},{$inc:{likenum:NumberInt(1)}})

updateOneupdateMany可以分别单条与多条的修改

2.3.4 文档的删除

使用remove()

db.collectionName.remove(条件)
#删除1或多个
db.comment.remove({content:"学姐好"})
db.comment.remove({useid:"10"})
#全部删除
db.comment.remove({})

deleteOne与deleteMany可以单条与多条的删除

2.4 文档的分页查询

2.4.1 统计查询

使用count()

db.collectionName.count(query,options)
  • query:查询条件
  • options:可选,修改计数的额外选项
#统计所有记录
db.comment.count()
#按条件统计记录
db.comment.count({likenum:10})

2.4.2 分页列表查询

使用limit()读取指定数量的数据,skip()跳过指定数量的数据

db.collectionName.find().limit(num).skip(num)
#跳过2条显示2条数据
db.comment.find().limit(2).skip(2)

2.4.3 排序查询

使用sort() 按某字段升序或降序查询 1为升序,-1位降序

db.collectionName.find().sort({KEY:1})
#对useid升序排列 相同id按点赞数升序
db.comment.find({},{useid:1,likenum1}).sort({useid:1,likenum:1})

尽量保证排序的字符串数据位数相同
sort排序会从首位比较

2.5 其他查询方式

2.5.1 正则的复杂条件查询

db.collectionName.find({字段:/正则/})
db.comment.find({content:/齐刷的/})

2.5.2 比较查询

< ,<= ,> ,>= ,!=

# >的使用 $gt
db.collectionName.find({字段:{$gt:值}})
# <的使用 $lt
db.collectionName.find({字段:{$lt:值}})
# >=的使用 $gte
db.collectionName.find({字段:{$gte:值}})
# <=的使用 $lte
db.collectionName.find({字段:{$lte:值}})
# !=的使用 $ne
db.collectionName.find({字段:{$ne:值}})
#查询点赞数大于两百的数据
db.comment.find({likenum:{$gt:200}})

2.5.3 包含查询

使用$in

db.colletionName.find({字段:{$in:["val1","val2"]}})
#查找id为1和2的数据
db.comment.find({useid:{$in:["1","2"]}})

2.5.4 条件连接查询

使用$and$or

db.collection.find({$and:[{},{},{}]})
db.collection.find({$or:[{},{},{}]})
#查找点赞数大于100小于1000的文档
db.comment.find({$and:[{likenum:{$gt:100}},{likenum:{$lt:1000}}]})
#查找id为1和2的文档
db.comment.find({$or:[{useid:"1"},{useid:"2"}]})

3 索引 - Index

  1. 索引介绍 - 类型与优点
  2. 索引的操作
  3. 索引的性能

3.1 概述

  • MongoDB的索引使用了B-Tree,MySQL是B+Tree,在结构上MySQL支持随机和顺序查找
  • 使用B树数据结构遍历结点,结点内使用顺序查找或二分查找去查找关键字,查找失败确定范围到下一级结点,直到查找成功或返回null
  • 使用索引可以减少查询的集合,不用遍历所有的集合提升查询效率

3.2 索引类型

3.2.1 单字段索引

  • 在文档的单字段上创建用户定义的升序/降序索引
  • 可以在任何方向上遍历索引

    #升序
    {userid:1}

3.2.2 复合索引

  • 多个字段的用户定义的索引
  • 先按一个去排序,相同的值按其他字段再排序

    #按id升序,相同id按num降序
    {userid:1,num:-1}

3.2.3 其他索引

  • 地理空间索引
    返回结果时使用平面几何的二维索引
    返回结果时使用球面几何的二维球面索引
  • 文本索引
    支持在搜索字符串内容,这些文本索引不存储特定语言的停止词,而将几何中的词作为词干,只存储词根
  • 哈希索引
    对字段值的散列进行索引,这些索引在其范围内的值分布更加随机,但支持相等匹配,不支持基于范围的查询

3.3 索引的管理操作

3.3.1 查看索引

  • 返回几何中所有索引的数组

    db.collectionName.getIndexes()
    #查询comment几何所有的索引
    db.comment.getIndexes()
    [ 
        { v: 2, key: { _id: 1 }, name: '_id_' } 
    ]

    默认以_id为索引

3.3.2 创建索引

  • 在集合上创建索引

    db.collectionName.createIndex(keys,options)

    keys:键值对文档,键为字段,值为1或-1。也可以是其他索引类型
    options:可选,控制索引创建的选项文档

    unique:<Boolean/> 索引是否唯一
    name:<String/> 索引名称,可以对复合索引重命名
    sparse:<Booeal/> 不存在的字段不启用索引
    weights:<document/> 索引权重值,优先级1-99999
    其他参数可参考文档

    #在comment上添加一个降序的索引
    db.comment.createIndex({useid:-1})
    #查看索引
    db.comment.getIndexes()
    [
        { v: 2, key: { _id: 1 }, name: '_id_' },
        { v: 2, key: { useid: -1 }, name: 'useid_-1' }
    ]

3.3.3 删除索引

  • 可以移除指定索引,或删除所有索引

1.指定删除

#删除指定索引
db.collectionName.dropIndex(index)

index 可以是name也可以是key

#删除comment集合的useid字段降序的索引
db.comment.dropIndex("useid_-1")
{ nIndexesWas: 2, ok: 1 }

2.删除全部

#删除全部索引
db.collectionName.dropIndexes()

_id是不会被删除的

3.4 使用索引

3.4.1 执行计划

  • 分析查询性能通 使用 执行计划来观察查询情况
  • 查询耗费的事件、是否基于索引查询

    db.collectionName.find(query,options).explain(options)
    #查询useid为2的文档
    db.comment.find({useid:"2"}).explain()

    返回的参数中 WinningPlanstage参数记录了查询的方式,索引还是全局

3.4.2 涵盖的查询

  • 当查询条件和查询投影仅包含索引字段时,MongoDB直接从索引返回结果
  • 不扫描任何文档或将文档带入内存

    #查询likenum为大于10的文档,仅返回likenum
    db.comment.createIndex({likenum:1})
    db.comment.find({likenum:{$gt:10}},{likenum:1,_id:0}).expalin()

    查询条件与返回的结果仅只有likennum,直接在likenum索引里遍历即可,不用遍历文档


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK