天天看點

MongoDB與Redis的簡單使用

MongoDB與Redis的簡單使用

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

資料展示:

MongoDB與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 少說話多讀書 閱讀(...) 評論(...) 編輯 收藏