mongodb

概念解析

SQL术语/概念 MongoDB术语/概念 解释说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

主要操作

登录数据库(root账号)

  • mongo -u "root" -authenticationDatabase admin -p

创建数据库与用户

# 切换数据库
> use test
use test

# 创建用户
> db.createUser({'user':'123', 'pwd':'123123', 'roles':[{'role':'readWrite', 'd
':'test'}]})

Successfully added user: {
        "user" : "123",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "test"
                }
        ]
}

# 显示用户
> show users

  • Built-In Roles(内置角色):
    1. 数据库用户角色:read、readWrite;
    2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
    3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
    4. 备份恢复角色:backup、restore;
    5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    6. 超级用户角色:root
    7. 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
    1. 内部角色:__system

用户登录

用户登录
> use test
switched to db test
> db.auth("123","123123")
1 (返回1,登录成功)

删除用户
> use test
switched to db test
> db.dropUser("123")
true
> db.dropAllUser()

删除数据库
> use test
> db.dropDatabase()

集合操作

# 数据列表
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

一个mongodb中可以建立多个数据库。
MongoDB的默认数据库为"db",该数据库存储在data目录中。

# 连接指定数据库
> use test
switched to db test

# 创建集合原型
> db.createCollection(<name>, { capped: <boolean>,
                              autoIndexId: <boolean>,
                              size: <number>,
                              max: <number>,
                              storageEngine: <document>,
                              validator: <document>,
                              validationLevel: <string>,
                              validationAction: <string>,
                              indexOptionDefaults: <document> } )

# 在test创建固定集合mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个
> db.createCollection("mycol", { capped : true, autoIndexId : true, size : 6142
00, max : 10000 } )

  {
          "note" : "the autoIndexId option is deprecated and will be removed in a
  future release",
          "ok" : 1
  }

# 通过插入数据的方式创建集合
> db.mycoll.insert({"info":"username"})
WriteResult({ "nInserted" : 1 })

# 查看所有的集合
> show tables
mycol
mycoll

> show collections
mycol
mycoll

# 删除集合
> db.mycoll.drop()
true

# 显示当前数据库对象和集合
> db
test

文档操作


# 插入文档
> use test
> show tables
mycol

> document=({title: '标题',
...     description: 'MongoDB 是一个 Nosql 数据库',
...     by: 'Allen',
...     url: 'http://www.baidu.com',
...     tags: ['mongodb', 'database', 'NoSQL'],
...     likes: 100
... });

> db.mycol.insert(document)
WriteResult({ "nInserted" : 1 })

# 查看集合数据量
> db.mycol.count()
1

# 查看已插入文档
> db.mycol.find()

{ "_id" : ObjectId("5d3e61263359db96129b480a"), "title" : "标题", "description"
: "MongoDB 是一个 Nosql 数据库", "by" : "Allen", "url" : "http://www.baidu.com",
 "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }

# 查看一条数据,并格式化输出
> db.mycol.findOne().pretty()

{ "_id" : ObjectId("5d3e61263359db96129b480a"), "title" : "标题", "description"
: "MongoDB 是一个 Nosql 数据库", "by" : "Allen", "url" : "http://www.baidu.com",
 "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }

# 通过标题去重,且likes >100
> db.mycol.distinct("title",{likes:{$gt:100}})

[ ]

# Mongodb更新有两个命令:update、save。
# 删除文档
  - db.collection.remove(
     <query>,
     {
       justOne: <boolean>,
       writeConcern: <document>
     }
    )
  - 参数说明:
    - query :(可选)删除的文档的条件。
    - justOne : (可选)如果设为 true 或 1,则只删除一个文档。
    -  writeConcern :(可选)抛出异常的级别。

查询

  • 查询likes >100的总数

    • db.mycol.find({"likes" : {$gt : 100}}).count()
      • 查询条件操作符:
        • (>) 大于 - $gt
        • (<) 小于 - $lt
        • (>=) 大于等于 - $gte
        • (<= ) 小于等于 - $lte
  • limit()方法

    • db.mycol.find({},{"title":1,_id:0}).limit(3)
  • Skip() 方法

    • db.mycol.find({},{"title":1,_id:0}).skip(1)
  • sort()方法

    • db.mycol.find({},{"title":1,_id:0}).sort({"likes":-1})
  • aggregate聚合

    • MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: ObjectId(7df78ad8902d)
   title: 'NoSQL Overview', 
   description: 'No sql database is very fast',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 10
},
{
   _id: ObjectId(7df78ad8902e)
   title: 'Neo4j Overview', 
   description: 'Neo4j is no sql database',
   by_user: 'Neo4j',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
}

# 计算每个作者所写的文章数。通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
   "result" : [
      {
         "_id" : "runoob.com",
         "num_tutorial" : 2
      },
      {
         "_id" : "Neo4j",
         "num_tutorial" : 1
      }
   ],
   "ok" : 1
}

备注:类似于SQL语句
  - select by_user, count(*) from mycol group by by_user

聚合的表达式:

表达式 描述 实例
$sum | 计算总和 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

管道的概念

管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

聚合框架中常用的几个操作:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。
import pymysql
import contextlib
from pymongo import MongoClient
from config import  MONGO_DB,DOCNAME,MONGO_USER,MONGO_PSW,MONGO_HOST,MONGO_PORT,MONGO_DB,MARIADB_HOST,MARIADB_PORT,MARIADB_USER,MARIADB_PSW,MARIADB_DB

class Pretreatment(object):

    def __init__(self, user=MONGO_USER, psw=MONGO_PSW, host=MONGO_HOST, port=MONGO_PORT, mdb=MONGO_DB):

        # mongoDB连接
        uri = 'mongodb://' + user + ':' + psw + '@' + host + ':' + port + '/' + mdb
        client = MongoClient(uri)
        db = client[MONGO_DB]
        self.find_port = db[DOCNAME]

        # mysql连接
        self.conn = pymysql.connect(host=MARIADB_HOST,
                                    port=MARIADB_PORT,
                                    user=MARIADB_USER,
                                    passwd=MARIADB_PSW,
                                    db=MARIADB_DB,
                                    charset="utf8")        
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 搭配with可以实现自动关闭释放资源
    @contextlib.contextmanager
    def mysql(self):
        try:
            yield self.cursor
        finally:
            self.conn.commit()
            self.cursor.close()
            self.conn.close()

    def demo(self):
        with self.mysql() as cursor:
            pass

redis

数据展示:


# 登录
C:\Users\Administrator> redis-cli

# 选择2号数据库
127.0.0.1:6379> select 2
OK

# 从0号游标开始筛选2号库中DB开头的集合
127.0.0.1:6379[2]> scan 0 match DB*
1) "0"   (开始第二次迭代的游标值,如果返回值为0,则已经迭代完数据)
2) 1) "DB_URL201906"

# 显示当前数据库中所有的集合
127.0.0.1:6379[2]> KEYS *

# 判断该集合的类型
127.0.0.1:6379[2]> type DB_URL201906
zset

# 查找有序集合(zset)对应的命令
127.0.0.1:6379[2]> zscan DB_URL201906 0
1) "128"
2)  1) "http://abc1123/1047238.html"
    2) "20190728223915"
    3) "http://abc1123/183200.html"
    4) "20190728223915"
    5) "http://abc1123/189858.html"
    6) "20190728223915"
    7) "http://abc1123/105179.html"
    8) "20190728223915"
    9) "http://abc1123/322960.html"

一小段Python封装

import redis
from config import REDIS_KEY,REDIS_HOST,REDIS_PORT,REDIS_PASSWORD,REDIS_DB

class RedisClient(object):
    def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, db=REDIS_DB):
        """
        初始化
        :param host: Redis 地址
        :param port: Redis 端口
        :param password: Redis密码
        """
        self.db = redis.StrictRedis(host=host, port=port, decode_responses=True, db=db)

    def add(self, url, value=init_value):
        """
        :param url: url
        :param value: 时间
        :return: 添加结果
        """
        if not self.db.zscore(REDIS_KEY, url):
            return self.db.zadd(REDIS_KEY, value, url)

    def exists(self, url):
        """
        判断是否存在
        :param url:
        :return: 是否存在
        """
        return not self.db.zscore(REDIS_KEY, url) == None

    def all(self,min_value,max_value):
        """
        获取值在(min_value,max_value)之间的数据
        :return: 数据列表
        """
        return self.db.zrangebyscore(REDIS_KEY, min_value, max_value)

Posted on 2019-07-29 17:52  少说话多读书  阅读(2859)  评论(0编辑  收藏  举报