mongo速记一

2019-05-25  本文已影响0人  勤劳的evan

一. 概述

就和描述里提到的一样,这次依旧是简单使用.crud以及聚合(管道)简单介绍.而且是基于单实例.写这个主要还是留作备份,以免以后长时间不用忘记了,到时候完整的看官方文档比较耗时间.所以这篇blog更多的是说明以及使用的一个例子.更多的option或者command不会列出,实际使用时可查寻官方文档~

当然这里的所有内容都可以在官网文档中找到~

二.素材准备

可以到官网下载server以及mongo shell

下载地址

三.安装以及数据库准备

我这边是debian,所以下载的是deb文件直接dpkg -i就可以了.
然后就是启动以及配置问题.很多选项都可以通过命令行的形式指定,但是这边还是建议通过配置文件来实现.默认的配置文件位于/etc/mongo.conf.这边可以复制出来修改使用.

首先是storage也是是数据存储部分.debian下默认是在 /var/lib/mongodb,自然可以根据自己的需求来配置,修改下图的dbPath即可

storage:
    dbPath: /var/lib/mongodb

systemLog部分则是日志存储位置,同样依照自己的需求修改即可

systemLog:
    destination: file
    logAppend: true
    path: /var/log/mongodb/mongod.log

然后是通信的端口以及监听IP.这个和socket一样,可以选择本地还是内网还是公网.

net:
    port: 27017
    bindIp: 127.0.0.1

这是他的默认配置也就是说仅仅支持本地访问.如果需要的可以在后面继续添加,比如增加局域网访问

bindIp: 127.0.0.1,192.168.111.111

当然你也可以选择0.0.0.0 直接监听所有网络请求.

security:
    authorization:enabled

这个则是开启用户认证的模块.(还有很多内容参见官网,比如fork,oplogSize等)

不过在开启之前需要新建一个用户,并且设置为admin用户,不然这个用户鉴权部分也就没有意义了.

新建用户:

db.createUser({user:"myAdmin",pwd:"xxxx",roles:[{role:"userAdminAnyDatabase",db:"admin"},{role:"dbAdmin",db:"admin"},{role:"clusterAdmin",db:"admin"}]})

这里简单说明下,userAdminAnyDatabase 则是赋予myAdmin用户所有db的用户管理权限,dbAdmin自然是管理自己的admin,clusterAdmin 则是集群的.这边如果遇到db.auth 认证日志出现两次结果,一次成功,一次replSet认证失败可以添加这个权限以继续下面的操作.

还有就是admin用户仅仅是管理功能,并不包含read 和 write 权限.
当然权限还有很多,具体的可以参考这个链接的文章.

现在创建一个新的测试库,use 一个不存在的库他会自动创建

use testdb

这时候其实在show dbs的时候 testdb是不可见的,只有在插入数据的时候才可见.

新建testdb的管理员:

db.createUser({user:"testdbAdmin",pwd:"xxxx",roles:[{role:"dbAdmin",db:"testdb"},{role:"dbOwner",db:"testdb"}]})

用户创建成功后就可以退出重新用testdb用户登录了:

use testdb
db.auth({user:"testdbAdmin",pwd:"xxxx"})

如果返回1就是认证成功了.

创建一个测试集合testC并插入第一条数据(同样不存在自动创建):

db.testC.insert({name:"first"})

如果返回WriteResult({"nInserted":1})则说明插入成功了,这时候如果在另外一个mongo shell中myAdmin用户登录,查看所有数据库show dbs会发现testdb 已经可以正常显示了.

四.CRUD

插入:

db.collectionName.insert()
db.collectionName.insertOne({xxx:xxx})
db.collectionName.insertMany([{xxx:xxx},{xxx:xxx}])
db.testC.insertOne({name:"first"})
db.testC.insertMany([{name:"first"},{name:"second"},{name:"third"},{name:"toDelete"}])

如果没有指定_id字段,mongo则会自动生成该字段作为索引.(对于批量操作还有有序和无序之分,具体参见官方文档)

查询:

db.collectionName.find(<filter>,<projection>)

filter 是查询条件,projections是投影,其实是对数据做一些限制

// select * from testC
db.testC.find()
// select name from testC where name >= "third" or _id = ObjectId("5ce91317811bea15014713f5");

db.testC.find({$or:[{name:{$gte:"third"}},{_id:ObjectId("5ce91317811bea15014713f5")}]},{_id:0})

这条语句的大体意思和注释类似,其中_id:0 的意思是_id 字段不返回,其余类似or的还有and,类似gte的还有gt,lte,lt,ne,in等.

结果如下:

{ 
    "name" : "first"
}
{ 
    "name" : "third"
}
{ 
    "name" : "todrop"
}

删除:

db.collectionName.deleteOne()
db.collectionName.deleteMany()
db.colletcionName.drop()

drop则是删除对应集合中的所有文档.

// delete from testC where name = "todrop"
db.testC.deleteOne({name:"todrop"})

更新

// db.collection.update( criteria, objNew, upsert, multi )
db.collectionName.updateOne(<filter>, <update>, <options>)
db.collectionName.updateMany(<filter>, <update>, <options>)
db.collectionName.replaceOne(<filter>, <update>, <options>)
// update testC set name = "1" where name = first
// updateOne 则是只更新一条.老版本是有update方法的,会有option true or false 指定更新一条还是多条 就是multi这个字段,upsert 则是指定未查询到时是否创建

db.testC.updateMany({name:"first"},{$set:{name:"1"}})

五.聚合

这个有点类似管道就是数据一轮一轮的处理

db.collectionName.aggregate(AGGREGATE_OPERATION)

这个这里也仅仅是提示下有这种用法,这是一个示例

db.collectionName.aggregate([
    {
        // filter1
        $match:{
            "_id":{$gte:ObjectId("xxx"),$lt:ObjectId("xxx")}
        }
    },
    {
        //filter2
        $match:{
                "field1":{$in:[
                            '111',
                            '222',
                            '333',
                            '444'
                          ]
                     },
               "field2":filedValue2
             }                              
    },
                              
    {
        //aggregate
        $group:{
                _id:"$columnName",
                count:{$sum:1},
                alias1:{$sum:"$field3"},
                alias2:{$sum:"$field4"}
            }
    }
                              
])

这里简单说明下:这段语句的意思就是首先经过filter1的数据再经过filter2的过滤(先按照filter1的索引过滤这样第二个filter会快点),后面则是按照columnName字段分组,count:{$sum:1}则是统计行数作为count,这里$sum如果不指定字段则是统计行数,统计field3的和作为alias1的值,统计field4的和作为alias2的值

举个小例子
数据如下:

db.testC.insertMany(
    [
        {name:"first",age:1,city:"shanghai",score:90},
        {name:"second",age:2,city:"shanghai",score:91},
        {name:"third",age:3,city:"shanghai",score:92},
        {name:"fourth",age:4,city:"nanjing",score:93},
        {name:"fifth",age:5,city:"nanjing",score:94},
        {name:"left",age:4,city:"unknow",score:100}
    ]
)

执行语句如下:其中5ce925cf10bc5eb4a70f8782是first的_id值

db.testC.aggregate([
    {
      $match:{
        "_id":{$gt:ObjectId("5ce925cf10bc5eb4a70f8782")}
      }
    },
    
    {
      $match:{"city":{$in:[
            "shanghai",
            "nanjing"
          ]}}
    },
    
    {
        $group:{
            _id:"$city",
            count:{$sum:1},
            ageSum:{$sum:"$age"},
            scoreSum:{$sum:"$score"}
        }
    }
])

结果如下:

{ 
    "_id" : "nanjing", 
    "count" : NumberInt(2), 
    "ageSum" : 9.0, 
    "scoreSum" : 187.0
}
{ 
    "_id" : "shanghai", 
    "count" : NumberInt(2), 
    "ageSum" : 5.0, 
    "scoreSum" : 183.0
}

六.补充

这里很多内容没有涉及,例如索引以及事务副本集等.均可以参考官方文档.还有就是可以通过部分可视化工具简化操作例如mongochef等

上一篇下一篇

猜你喜欢

热点阅读