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)
- 内部角色:__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
- 查詢條件操作符:
- db.mycol.find({"likes" : {$gt : 100}}).count()
- 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 少說話多讀書 閱讀(...) 評論(...) 編輯 收藏