爬蟲(六)——存儲庫(一)MongoDB存儲庫

存儲庫——MongoDB

1、安裝MongoDB 4.0

一、安裝

(1)能夠去官網下載(我是直接選擇msi文件的)正則表達式

https://www.mongodb.com/download-centersql

1554126799103

(2)運行文件,能夠自定義(custom)安裝,注意安裝的時候必定要把勾去掉 「Install MongoDB Compass」方便操做,以後一直下一步mongodb

1554126938387

安裝完成之後,文件目錄 以下圖shell

1554127282662

(3)添加安裝MongoDB的bin目錄到環境變量中數據庫

1554127053796

(4)測試,cmd打開控制檯,而後輸入mongo回車,能夠進入MongoDB的shell中,輸入show dbs能夠看到數據庫。表示裝成功編程

1554127125857

二、修改數據庫文件和日誌保存位置設置(可不改)

MongoDB的數據保存位置和日誌位置與其服務的配置文件 mongod.cfg有關,該文檔可在 「安裝目錄\bin"下找到。裏面記錄了dbpath(數據庫保存位置),logpath(日誌文件保存位置),還有鏈接網絡bind_ip等。數組

1554127453682

這裏MongoDB安裝在E盤,可是想將數據庫和日誌文件等保存在其餘盤,因此修改dbpath和logpath成本身想要的路徑就好網絡

1554127523888

修改完之後要重啓服務編程語言

net stop MongoDB
net start MongoDB

三、帳戶管理、遠程服務

安裝完成後MongoDB默認只能本機訪問,而且不須要密碼;下面咱們添加用戶並開啓遠程服務

(1)打開cmd輸入mongo進入MongoDB;進入admin數據庫(建立新的數據庫)

> use admin

(2)在庫中建立用戶

db.createUser({
    user: "root", 
    pwd: "123", 
    roles: [
        {role: "root",db: "admin"}
    ]
})
# 亦能夠一個用戶對多個數據庫管理
角色類型 權限級別
普通用戶角色 read、readWrite
數據庫管理員角色 dbAdmin、dbOwner、userAdmin
集羣管理員角色 clusterAdmin、clusterManager、clusterMonitor、hostManager
數據庫備份與恢復角色 backup、restore
全部數據庫角色 readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
超級用戶角色 root
核心角色 __system

(3)修改容許遠程鏈接

修改默認配置文件bin/mongod.cfg中的bingIp中127.0.0.10.0.0.0,這裏能夠實現其餘網段地址的鏈接;(千萬不要將這句註釋,不然服務可能沒法啓動)

1554128453049

#security:的註釋去掉,而後添加authorization: enabled注意authorization前面要有兩個空格

1554128610888

(4)重啓數據庫

net stop MongoDB   
net start MongoDB

(5)測試

若是測試結果以下,則表示用戶設置成功

# 登陸方式一
mongo 127.0.0.1:27017/admin(數據庫名字) -u root(用戶名) -p 123(密碼)

# 登陸方式二
> mongo
> use test
>db.auth("sb","sb123")           # 必需要用雙引號

# 登陸方式三
mongo --port 27017 -u "root" -p "123" --authenticationDatabase "admin"

1554129639564

3、MongoDB數據庫操做

一、對庫操做

# 1.增長數據庫
use 數據庫名      # 存在則切換到該數據庫,不存在則新建數據庫

# 2.查看數據庫
show dbs

# 3.刪除數據庫
use test    # 先切換到要刪的庫下
db.dropDatabase()    # 刪除當前庫

# 幫助查看全部庫相關操做-- db.help()
db.help()

二、對集合操做——相似表

use test  # 先切換到數據庫下

# 1.新增集合
db.user    # 建立user表

# 2.查看集合
show tables
# 或者 show colletions

# 3.刪除集合
db.user.drop()

# 幫助查看全部集合相關操做-- db.(集合名).help()
db.user.help()

三、對文檔操做—— 相似記錄

MongoDB中存儲的文檔必須有一個"_id"鍵。這個鍵的值能夠是任意類型,默認是個ObjectId對象。
在一個集合裏,每一個文檔都有惟一的「_id」,確保集合裏每一個文檔都能被惟一標識。
不一樣集合"_id"的值能夠重複,但同一集合內"_id"的值必須惟一
ObjectId是"_id"的默認類型,ObjectId採用12字節的存儲空間,是一個由24個十六進制數字組成的字符串
    0|1|2|3|   4|5|6|     7|8    9|10|11    
    時間戳      機器      PID    計數器

若是插入文檔時沒有"_id"鍵,系統會自幫你建立 一個

(1)增長文檔—— insert()

use test  # 先切換到數據庫下

db.user.insert({'_id':1,'name':'tom'})     # id要用_id做爲key
# 或者數據量較大時使用變量:
user0={
    "name":"egon",
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'BJ'
    }
}

db.test.insert(user0)

# 插入多條數據  ---- insertMany([...])
user1={
    "_id":1,
    "name":"alex",
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'weifang'
    }
}

user2={
    "_id":2,
    "name":"wupeiqi",
    "age":20,
    'hobbies':['music','read','run'],
    'addr':{
        'country':'China',
        'city':'hebei'
    }
}

db.user.insertMany([user1,user2])
# save() 方法
use test
db.save({'_id':1,'name':'tom'})    # 有相同的id,則覆蓋原數據;沒有該id,則新增數據
db.save({'a':123})     # 不指定id,和新增數據相同

(2)查看文檔—— find()

use test

# 1.查找全部
db.user.find()

# 按條件查詢
#(1)比較運算
!=  ----    {'$ne':3}   # 不等於3
>   -----    {'$gt':2}  # 大於2
<    ----    {'$lt':2}   # 小於2
>=   ----    {'$gte':4}   # 大於等於
>=   ----    {'$lte':4}   # 小於等於

db.user.find({'_id':3})
db.user.find({'_id':{'$ne':3}})    # id不等於3
db.user.find({'name':{'$ne':'Tom'}})    # 名字不是Tom


# (2)邏輯運算   and   not    or
and ----- {'$and':[....]}
not ----- {'$not':...}
or ----- {'$or':[....]}

# id>=2 and id<=4
db.user.find({'_id':{"$gte":2,"$lt":4}})

# id >= 2 and age < 40;
db.user.find({"_id":{"$gte":2},"age":{"$lt":40}})
# 或者
db.user.find({
    '$and':[
        {"_id":{"$gte":2}},
        {"age":{"$lt":40}}
    ]
})

# id >= 5 or name = "alex";
db.user.find({
    "$or":[
        {'_id':{"$gte":5}},
        {"name":"alex"}
     ]
})

# id % 2=1    id取模2等於1
db.user.find({'_id':{"$mod":[2,1]}})

# 取反  取id爲奇數
db.user.find({'_id':{
    '$not':{
        '$mod':[2,0]
    }
}})


# (3)成員運算  in,not in
in   -----   {'$in':[....]}
not in -------{'$nin':[]}

db.user.find({'name':{'$in':['ton','eton']}})


# (4)正則匹配  regexp
regexp -----  /正則表達/i
    i 忽略大小寫
    m 多行匹配模式
    x 忽略非轉義的空白字符
    s 單行匹配模式

db.user.find({'name':/^T.*?(g|n)/i})


# (5)查詢指定字段
1  ---  表示須要
0  ----  不須要,默認

# 只要name,age
db.user.find(
    {'name':'Tom'},
    {'name':1,
     'age':1,
     '_id':0
    }
)


# (6)查詢數組
既有... 又有...     -----    {'$all':[...,...]}
第n個     ----    key.n
要n個    -----    {'$slice':n}   # -n表示後n個
A下的B是C   -----    {'A.B':C}

# 查看有dancing愛好的人
db.user.find({'hobbies':'dancing'})

# 查看既有dancing愛好又有tea愛好的人
db.user.find({
    'hobbies':{
        "$all":['dancing','tea']
        }
})

# 查看第4個愛好爲tea的人
db.user.find({"hobbies.3":'tea'})

# 查看全部人最後兩個愛好
db.user.find({},{'hobbies':{"$slice":-2},"age":0,"_id":0,"name":0,"addr":0})

# 查看全部人的第2個到第3個愛好
db.user.find({},{'hobbies':{"$slice":[1,2]},"age":0,"_id":0,"name":0,"addr":0})


# (7)排序
sort()
1   -----   升序
-1  -----   降序
# 排序:--1表明升序,-1表明降序
db.user.find().sort({"name":1,})
db.user.find().sort({"age":-1,'_id':1})


# (8)分頁
limit   -----   取幾個
skip   ------   跳過幾個再開始取

# 跳過兩個之後,取一個
db.user.find().limit(1).skip(2)


# (9)獲取數量
count()

db.user.count({'age':{'$gte':20}})


# (10)key的值爲null或者沒有這個key
db.t2.find({'b':null})

(3)修改文檔——update()

update() 方法用於更新已存在的文檔。語法格式以下:
db.collection.update(
   <query>,   # 查詢條件,條件爲空,表示全部文檔
   <update>,
   {
     upsert: <boolean>, # 默認爲false,表明若是不存在update的記錄不更新也不插入,設置爲true表明插入
     multi: <boolean>,   # 默認爲false,表明只更新找到的第一條記錄,設爲true,表明更新找到的所有記錄
     writeConcern: <document>
   }
)
參數說明:對比update db1.t1 set name='EGON',sex='Male' where name='egon' and age=18;
# 1.覆蓋式修改
db.user.update({
    {'name':'tom'},
    {'sex':'male','phone':'123123'}
})

# 2.局部修改 ----  {'$set':{修改的數據}}
db.user.update({
    {'name':'tom'},
    {'$set':{'sex':'male','phone':'123123'}}
})

# 3.批量修改
db.user.update({
    {'name':'tom'},
    {'$set':{'sex':'male','phone':'123123'}},
    {'multi':True}
})

# 4.有則修改,無則新增
db.user.update({
    {'name':'tom'},
    {'$set':{'sex':'male','phone':'123123'}},
    {'multi':True,
     'upsert':True
    }
})

# 5.嵌套數據修改 ----   「 . 」號
# 城市的國家修改,第二個愛好修改
db.user.update({
    {},
    {'$set':{'city.country':'China','hobbies.1':'eat'}},
    {'multi':True,
     'upsert':True
    }
})
# 增長1  ------  {'$inc'}
db.user.update(
    {},
    {
        "$inc":{"age":1}
    },
    {
        "multi":true
    }
)
# 添加刪除數組內元素   ----    $push  $pop    $pull
# 1.增長愛好
db.user.update({"name":"yuanhao"},{"$push":{"hobbies":"read"}})

# 2.爲名字爲yuanhao的人一次添加多個愛好tea,dancing
db.user.update(
    {"name":"yuanhao"},
    {
        "$push":{
            "hobbies":{
                "$each":["tea","dancing"]
            }
        }
    }
)

# 3.刪除數組元素  ---- $pop()  兩頭刪
-1    ----   從頭開始刪1個
1     -----   從末尾開始刪1一個
db.user.update(
    {"name":"yuanhao"},
    {"$pop":{"hobbies":1}}
)

# 4.按照條件刪    -----  pull() 根據條件刪
# 刪除全部人的read愛好
db.user.update(
    {'addr.country':"China"},
    {"$pull":{"hobbies":"read"}},
    {
        "multi":true
    }
)

(4)刪除文檔——deleteOne() / deleteMany()

# 一、刪除多箇中的第一個
db.user.deleteOne({ 'age': 8 })

# 二、刪除國家爲China的所有
db.user.deleteMany( {'addr.country': 'China'} ) 

# 三、刪除所有
db.user.deleteMany({})

4、MongoDB基本數據類型

MongoDB在保留了JSON基本鍵/值對特性的基礎上,添加了其餘一些數據類型。在不一樣的編程語言下,這些類型的確切表示有些許差別。

# 一、null:用於表示空或不存在的字段
d={'x':null}

# 二、布爾型:true和false
d={'x':true,'y':false}

# 三、數值
d={'x':3,'y':3.1415926}

# 四、字符串
d={'x':'egon'}

# 五、日期
d={'x':new Date()}
d.x.getHours()

# 六、正則表達式
d={'pattern':/^egon.*?nb$/i}

正則寫在//內,後面的i表明:
    i 忽略大小寫
    m 多行匹配模式
    x 忽略非轉義的空白字符
    s 單行匹配模式

# 七、數組
d={'x':[1,'a','v']}

# 八、內嵌文檔
user={'name':'egon','addr':{'country':'China','city':'YT'}}
user.addr.country

# 九、對象id:是一個12字節的ID,是文檔的惟一標識,不可變
d={'x':ObjectId()}

5、聚合

一、篩選—— $match

aggregate()
$match    # 條件,和where,having相似
$group    # 分組,和group by相似
$字段名  # 表示取該字段的值

# select * from db1.emp where id > 3 group by post having avg(salary) > 10000;
db.emp.aggregate(
    {"$match":{"_id":{"$gt":3}}},
    {"$group":{"_id":"$post",'avg_salary':{"$avg":"$salary"}}},  # 這個_id表示分組依據
    {"$match":{"avg_salary":{"$gt":10000}}}
)

二、投射—— $project

  • 將一些字段不須要的去掉,額外須要的新增
  • 投射既能夠在起始時使用,也能夠在中間使用
{"$project":{"要保留的字段名":1,"要去掉的字段名":0,"新增的字段名":"表達式"}}

# 表達式之數學表達式
{"$add":[expr1,expr2,...,exprN]}    # 相加
{"$subtract":[expr1,expr2]}     # 第一個減第二個
{"$multiply":[expr1,expr2,...,exprN]}   # 相乘
{"$divide":[expr1,expr2]}   # 第一個表達式除以第二個表達式的商做爲結果
{"$mod":[expr1,expr2]}  # 第一個表達式除以第二個表達式獲得的餘數做爲結果


# 表達式之日期表式:
{"$year":"$date"}
{"$month":"$date"}
{"$week":"$date"}
{"$dayOfMonth":"$date"}
{"$dayOfWeek":"$date"}
{"$dayOfYear":"$date"}
{"$hour":"$date"}
{"$minute":"$date"}
{"$second":"$date"}

# 獲取員工的名字和工做年限
db.emp.aggregate(
    {"$project":{"name":1,"hire_year":{"$year":"$hire_date"}}}
)


# 字符串表達式
{"$substr":[字符串/$值爲字符串的字段名,起始位置,截取幾個字節]}
{"$concat":[expr1,expr2,...,exprN]}     # 指定的表達式或字符串鏈接在一塊兒返回,只支持字符串拼接
{"$toLower":expr}
{"$toUpper":expr}

# 全部人的名字變大寫
db.emp.aggregate(
    {"$project":{'new_name':{'$toUpper':'$name'}}}
)

# 投射示例
# 獲取員工的name、post、目前年齡
db.emp.aggregate(
    {"$project":{
        "name":1,
        "post":1,
        "new_age":{"$add":["$age",1]}
        }
})

三、分組—— $group

{"$group":{"_id":分組字段,"新的字段名":聚合操做符}}    # 這裏的_id表示根據什麼分組


# 分組後聚合得結果,相似於sql中聚合函數的聚合操做符:$sum、$avg、$max、$min、$first、$last
# select post,max(salary) from db1.emp group by post; 
db.emp.aggregate({"$group":{"_id":"$post","max_salary":{"$max":"$salary"}}})

# 求每一個部門的人數
db.emp.aggregate({"$group":{"_id":"$post","count":{"$sum":1}}})

四、排序— $sort,限制— $limit,跳過— $skip

{"$sort":{"字段名":1,"字段名":-1}}    # 1升序,-1降序
{"$limit":n}    # 限制,取n條數據
{"$skip":n}     # 跳過多少個文檔

# 取平均工資最高的前兩個部門,先按平均公司排序,若工資同樣再按id排序
db.emp.aggregate(
    {
        "$group":{"_id":"$post","平均工資":{"$avg":"$salary"}}
    },
    {
        "$sort":{"平均工資":-1, "_id":1}
    },
    {
        "$limit":2
    }
)

6、隨機取幾個數據

$sample

# 隨機取3個文檔
db.users.aggregate(
   [ { $sample: { size: 3 } } ]
)

7、可視化工具

連接:https://robomongo.org/

8、python中操做MongoDB

from pymongo import MongoClient  # pip3 install pymongo

# 一、連接
client=MongoClient('mongodb://root:123@localhost:27017/')
# client = MongoClient('localhost', 27017)

# 二、use 數據庫,切換到庫
db=client['db2']    # 等同於:client.db1
# print(db.collection_names())

# 三、查看庫下全部的集合
print(db.collection_names(include_system_collections=False))

# 四、建立集合,切換到表
table_user=db['userinfo'] `# 等同於:db.user

# 五、插入文檔
import datetime
user0={
    "_id":1,
    "name":"egon",
    "birth":datetime.datetime.now(),
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'BJ'
    }
}

user1={
    "_id":2,
    "name":"alex",
    "birth":datetime.datetime.now(),
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'weifang'
    }
}
# res=table_user.insert_many([user0,user1]).inserted_ids
# print(res)
# print(table_user.count())

# 六、查找
# from pprint import pprint#格式化細
# pprint(table_user.find_one())
# for item in table_user.find():
#     pprint(item)

# print(table_user.find_one({"_id":{"$gte":1},"name":'egon'}))

# 七、更新
table_user.update({'_id':1},{'name':'EGON'})
 
# 八、傳入新的文檔替換舊的文檔
table_user.save(
    {
        "_id":2,
        "name":'egon_xxx'
    }
)
相關文章
相關標籤/搜索