文章目录

  • ​​1 MongoDB简介​​
  • ​​2 安装​​
  • ​​3.简单使用​​
  • ​​3.1 启动​​
  • ​​3.2 连接和登录​​
  • ​​3.3 退出和关闭数据库​​
  • ​​3.3.1 退出客户端​​
  • ​​3.3.2 关闭数据库进程:​​
  • ​​3.4 常用操作​​
  • ​​3.5 查询条件​​
  • ​​3.5.1 条件操作符​​
  • ​​3.5.2 排序​​
  • ​​4 Python操作MongoDB​​
  • ​​4.1 增​​
  • ​​4.2 查​​
  • ​​4.3 更新​​
  • ​​4.4 排序​​
  • ​​4.5 删除​​
  • ​​5 Gridfs和bson存储大文件​​
  • ​​5.1 Gridfs​​
  • ​​5.2 bson上传(<16m)​​

1 MongoDB简介

MongoDB 是由C++语言编写的,是一个基于分布式文件存储面向文档存储的开源数据库系统。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

  • 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName=“Sameer”,Address=“8 Gandhi Road”)来实现更快的排序。
  • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
  • 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
  • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
  • MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
  • Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
  • Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
  • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
  • MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
    ​​​参考​

2 安装

这里贴一个Mac安装的方式 ​​MongoDB
​​ 安装完启动server可能会报错像​​MongoDB: exception in initAndListen: 20 Attempted to create a lock file on a read-only directory: /d​​ 通过​​sudo chown -R $USER /data/db​​修改权限即可。

3.简单使用

3.1 启动

​/usr/local/mongdb/bin/mongod -port 10001 --dbpath /data/mongodb/ --logpath /var/mongodb/mongodb.log​​​,关于启动的具体参数可以查看​​MongoDB的启动与停止​​,写的挺详细。
还可以将相关参数配置成配置文件
​​​vim mongodb.conf​

port=10001 #代表端口号,如果不指定则默认为   27017    
dbpath= /data/mongodb/ # 数据库路径
logpath= /data/mongodb/ #日志路径
logappend=true #日志文件自动累加,而不是覆盖

启动命令: ​​/usr/loca/mongodb/bin/mongod -f mongodb.conf​​​ 启动后可能会报错​​Access control is not enabled for the database​​,这里我们添加一个用户即可,见下方连接与登录参考。
查询端口来验证是否启动​​netstat -lanp | grep "27017"​​参考
启动的log可以参考

3.2 连接和登录

第一次启动可以使用​​mongo​​​,linux ​​./mongo​注意:如果启动服务器设置的不是默认端口,这里启动需要指定端口,如​​mongo -port 27018​​ 启动后,添加启动账号密码:

  • 先使用“use admin”命令,切换到admin数据库:。
  • db.addUser(“name”,“pass”);添加管理员账户。

添加完后,重启数据库服务,带–auth参数启动:
mongod --dbpath=/home/mongodb/dbfile/data_file/ --logpath=/home/mongodb/dbfile/log_file --auth --fork;

这样就会开启安全检查。服务器启动完后。在用mongo连接,然后用db,auth(“name”, “pass”)函数来登录。这样才有操作的权限。

  • 在admin数据库添加的账户都是超级管理员账号。
  • 要给具体的数据库设置专用的管理员,先用use databaseName命令切换到对应的数据库,在调用db.addUser(“name”,“pass”);函数来添加账户就行。
  • Mongo中超级管理员账号与其它数据库不同,当新建一个数据库,超级管理员也无法操作,需要新建对应该数据库的用户 ​​新建数据库出现"errmsg" : "not authorized on kgraph to execute command​​,并且当在数据库内切换用户后经常出现"errmsg" : “too many users are authenticated”,建议重新登录该用户
    例如​​​mongo -u "kg" -p "123" --authenticationDatabase "kgraph"​​,因为要切换的用户可能在当前数据库没有权限,而切换过后就会出现上述错误。
  • 查看当前数据库有哪些用户,可以在db.auth()登录后,使用:db.system.users.find();函数来查询。​​参考​​

3.3 退出和关闭数据库

3.3.1 退出客户端

如果已经用mongo登录到数据库了,可以使用"ctrl+c"来退出mongo客户端(服务器不会关闭),

3.3.2 关闭数据库进程:

  • 使用kill PID -2来关闭mongodb服务器(不要使用-9参数,会导致数据库文件损坏)。
  • 登录mongo客户端之后,切换到admin数据库,再调用db.shutdownServer()函数来关闭mongodb服务。

3.4 常用操作

查看数据库​​show dbs​​​ 选择或创建数据库​​use DATABASE_NAME​​ 查看集合​​show tables/collections​​ 删除数据库​​db.dropDatabase()​​ 创建集合

db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean>, size: <number>, max <number>} )

name:集合的名字
capped:是否启用集合限制,如果开启需要制定一个限制条件,默认为不启用,这个参数没有实际意义
size:限制集合使用空间的大小,默认为没有限制
max:集合中最大条数限制,默认为没有限制
autoIndexId:是否使用_id作为索引,默认为使用(true或false)
size:的优先级比max要高

删除集合​​db.collection.drop()​​​ 插入文档,mongo自动创建集合​​db.col.insertOne({"name" : "基础学习"})​​,这里创建了​​col​​的集合
向集合插入多条数据 ​​db.collection.insertMany()​​ 查找集合 ​​db.col.find()​

删除文档​​db.inventory.deleteOne( { status: "D" } )​​​和​​db.inventory.deleteMany({})​​ 更新文档

db.collection.update(
<query>,#update的查询条件,类似sql update查询内where后面的
<update>,#update的对象和一些更新的操作符(如$,$inc...)等
{
upsert: <boolean>,#可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi: <boolean>,#可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern: <document>#可选,抛出异常的级别。
}
)
#样例
db.getCollection('zhongcao_verified_topic').update({'date':{$gte:'2021-10-20'}}, {$set: {'date':'2021-10-21 13:30:00'}}, {multi:true})

集合查看​​db.col.find()​​​和​​db.col.find().pretty()​​​ # ​​pretty​​​以格式化的方式显示所有文档
指定读取的记录数​db.COLLECTION_NAME.find().limit(NUMBER)​跳过指定数量的数据​db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)​

更新集合​​db.collection.update()​​​例如​​db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})​​​ 以上详细的可以查看​​菜鸟教程​

3.5 查询条件

And ​​db.col.find({key1:value1, key2:value2}).pretty()​​​ Or ​​db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()​​ 等于 ​​{<key>:<value>}​​ 小于 ​​{<key>:{$lt:<value>}}​​ 小于等于 ​​{<key>:{$lte:<value>}}​​ 大于 ​​{<key>:{$gt:<value>}}​​ 大于等于 ​​{<key>:{$gte:<value>}}​​ 不等于 ​​{<key>:{$ne:<value>}}​​ 具体查看​​菜鸟教程​

3.5.1 条件操作符

MongoDB可以使用的类型:

  • Double 1
  • String 2
  • Object 3
  • Array 4
  • Binary data 5
  • Undefined 6 已废弃
  • Object id 7
  • Boolean 8
  • Date 9
  • Null 10
  • Regular Expression 11
  • Javascript 13
  • Symbol 14
  • Javascript(with scope) 15
  • 32-bit integer 16
  • Timestamp 17
  • 64-bit integer 18
  • Min key 255
  • Max key 127

获取"col"集合中title为String的数据​​db.col.find({"title" : {$type : 2}})​​​ ​​db.col.find({"title" : {$type : 'string'}})​

3.5.2 排序

​db.COLLECTION_NAME.find().sort({KEY:1})​注意:skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()。

4 Python操作MongoDB

Python操作与终端数据库操作类似。
​​​本处引用自​​推荐一篇不错的文章

import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
conn = MongoClient('172.*.*.*', 27017)
mydb = conn['hadoop']
dblist = conn.list_database_names() #列出db name
mycol = mydb.list_collection_names() #列出col name

mydb = myclient["db_name"]
mycol = mydb["col_name"]

4.1 增

mydict = { "name": "mongo", "type": "database"}
x = mycol.insert_one(mydict)
print(x)

<pymongo.results.InsertOneResult object at 0x7f93fad94988>
#如果我们在插入文档时没有指定 _id,MongoDB 会为每个文档添加一个唯一的 id。
print(x.inserted_id)

5d64d1397b4237fc223a2982

4.2 查

x = mycol.find_one()

{'_id': ObjectId('5d5e025165fa335687a18690'), 'name': 'aaa'}


for x in mycol.find():#相当于find_all()
print(x)

#“_id”的值为1表示显示id,如果不想显示可设为0,当有一个0,其他都自动设为1
mycol.find_one({},{"_id":1,"name":1})

{'_id': ObjectId('5d5e025165fa335687a18690'), 'name': 'aaa'}

指定查询条件

myquery = { "name": "Google" }
mydoc = mycol.find(myquery)
for x in mydoc:
print(x)

{'_id': 2, 'name': 'Google', 'address': 'Google 搜索'}

查询"name"首字母大于"H"

myquery = { "name": { "$gt": "W" } }
mydoc = mycol.find(myquery)
for x in mydoc:
print(x)

{'_id': ObjectId('5d5e025165fa335687a18690'), 'name': 'aaa'}
{'_id': ObjectId('5d64d1397b4237fc223a2982'), 'name': 'mongo', 'type': 'database'}
{'_id': 5, 'name': 'Zhihu', 'address': '知乎'}

利用正则表达式查询字符串
查询"name"首字母为"R"的内容

myquery = { "name": { "$regex": "^R" } }
mydoc = mycol.find(myquery)
for x in mydoc:
print(x)

{'_id': 1, 'name': 'RUNOOB', 'cn_name': '菜鸟教程'}

返回指定条数的数据

myresult = mycol.find().limit(5)
for x in myresult:
print(x)

4.3 更新

myquery = { "cn_name": "菜鸟教程" }
newvalues = { "$set": { "cn_name": "菜鸟养成" } }
mycol.update_one(myquery, newvalues)
for x in mycol.find({"name":"RUNOOB"}):
print(x)

{'_id': 1, 'name': 'RUNOOB', 'cn_name': '菜鸟养成'}

update_one() 方法只能修匹配到的第一条记录,如果要修改所有匹配到的记录,可以使用 update_many()

myquery = { "name": { "$regex": "^R" } }
newvalues = { "$set": { "alexa": "123" } }
x = mycol.update_many(myquery, newvalues)
print(x.modified_count, "文档已修改")

1 文档已修改

4.4 排序

mydoc = mycol.find().sort("alexa",-1)#-1表示对字段 alexa 按降序排序:
for x in mydoc:
print(x)

4.5 删除

delete_one和delete_many

myquery = { "name": "RUNOOB" }
mycol.delete_one(myquery)
#删除后输出
for x in mycol.find().limit(5):
print(x)
myquery = { "name": {"$regex": "^F"} }
x = mycol.delete_many(myquery)
print(x.deleted_count, "个文档已删除")

删除集合​​mycol.drop()​

5 Gridfs和bson存储大文件

GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等),适合于不常改变但是经常需要连续访问的大文件。​​pymongo 利用gridfs构建大文件存储系统​​

5.1 Gridfs

import os
import sys
from gridfs import *
from pymongo import MongoClient
from datetime import datetime
from bson import binary

#连接数据库
client = MongoClient("localhost:27017",username="kg",password="123",authSource="kgraph")

#定义上传和下载的文件夹
up_path = "/Users/enjlife/Desktop/cv/"
do_path = "/Users/enjlife/Desktop/temp/"

#使用Gridfs获取数据库集合
db = client.kgraph
mycol = db.list_collection_names() # 查看集合列表
fs = GridFS(db, collection='pdfs')

#定义上传和下载函数
#批量上传 Gridfs
def gd_upload(fs,up_path):
for filename in os.listdir(up_path):
dic = {}
dic["fname"] = filename
# dic["上传时间"] = datetime.now()
content = open(up_path + filename,"rb").read()
fs.put(content,**dic)
def gd_download(fs,do_path):
for cursor in fs.find():
name = cursor.fname
content = cursor.read()
with open(do_path + name,"wb") as f:
f.write(content)


mycol = db.list_collection_names() # 查看集合列表,Gridfs会分两部分上传
#['pdfs', 'pdfs.files', 'pdfs.chunks']

#查看结果
col = db.pdfs.files
for x in col.find():
print(x)

5.2 bson上传(<16m)

接上面连接数据库获取的col

col = db.pdfs

def bs_upload(col,uppath):
dic = {}
dic["fname"] = "FastR-CNN.pdf"
data = open(up_path + "FastR-CNN.pdf","rb").read()
if not col.find_one({"fname":"FastR-CNN.pdf"}):
dic["bdata"] = binary.Binary(data)
col.insert(dic)

​​python利用mongodb上传图片数据 : GridFS 与 bson两种方式​​python下上传/下载各种格式文件到MongoDB数据库中

未完待续…