昆明网站制作方案,华为云免费云服务器,哪些企业需要网站建设的,软件开发标准文章目录 Ubuntu 22.04 安装 MongoDB后台启动 MongoDBshell 连入 MongoDB 服务 MongoDB 用户权限认证创建 root 用户开启认证重启 MongoDB 服务创建其他用户查看用户信息验证用户权限删除用户 skynet.db.mongo 模块使用authensureIndexfind、findOneinsert、safe_insertdelete、… 文章目录 Ubuntu 22.04 安装 MongoDB后台启动 MongoDBshell 连入 MongoDB 服务 MongoDB 用户权限认证创建 root 用户开启认证重启 MongoDB 服务创建其他用户查看用户信息验证用户权限删除用户 skynet.db.mongo 模块使用authensureIndexfind、findOneinsert、safe_insertdelete、safe_deleteupdate、safe_updateaggregatesafe_batch_insert、safe_batch_delete Ubuntu 22.04 安装 MongoDB
其他平台安装教程可参考官网https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/ 确定主机运行哪个 Ubuntu 版本配置一致的继续往下看
cat /etc/lsb-release安装 mongodb 社区版的相关依赖
sudo apt-get install libcurl4 libgssapi-krb5-2 libldap-2.5-0 libwrap0 libsasl2-2 libsasl2-modules libsasl2-modules-gssapi-mit openssl liblzma5 gnupg curl导入 MongoDB 公共 GPG 密钥
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | \sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg \--dearmor创建/etc/apt/sources.list.d/mongodb-org-7.0.list 列表文件
echo deb [ archamd64,arm64 signed-by/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list重新加载本地包数据库
sudo apt-get update安装最新的稳定版本
sudo apt-get install -y mongodb-org后台启动 MongoDB 配置 /etc/mongod.conf bindIp: 0.0.0.0fork: true
# mongod.conf# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/# Where and how to store data.
storage:dbPath: /var/lib/mongodb
# engine:
# wiredTiger:# where to write logging data.
systemLog:destination: filelogAppend: truepath: /var/log/mongodb/mongod.log# network interfaces
net:port: 27017bindIp: 0.0.0.0# how the process runs
processManagement:fork: truetimeZoneInfo: /usr/share/zoneinfo#security:#operationProfiling:#replication:#sharding:## Enterprise-Only Options:#auditLog:sudo mongod -f /etc/mongod.conf
执行后结果如下
about to fork child process, waiting until server is ready for connections.
forked process: 361
child process started successfully, parent exitingps -ef | grep mongod可以看到有mongod进程在后台运行 shell 连入 MongoDB 服务
mongoshmongodb 客户端连接工具安装时自带 成功连入使用 MongoDB 用户权限认证
创建 root 用户
在 MongoDB 中root 账号是具有最高权限的账号可以执行所有操作。
use admin
db.createUser({user:root, pwd:root,roles:[root]})开启认证
我们需要开启 MongoDB 的认证功能以确保只有经过认证的用户才能访问数据库。
/etc/mongod.conf
在启动配置文件中添加以下配置
security:authorization: enabled重启 MongoDB 服务认证功能才会生效。
重启 MongoDB 服务 官方描述Sending a KILL signal kill -9 will probably cause damage as mongod will not be able to cleanly exit. (In such a scenario, run the repairDatabase command.) 可以采用在 mongosh 连入数据库后执行下述指令来友好关闭服务进程。
use admin
db.shutdownServer()创建其他用户
在MongoDB中每个数据库都有自己的权限系统可以为每个数据库创建不同的账号并赋予不同的角色。
db.createUser({user: cauchy, pwd: root, roles: [{ role: readWrite, db: test}]})readWrite: https://www.mongodb.com/docs/manual/reference/built-in-roles/#mongodb-authrole-readWrite
roles 可参考https://www.mongodb.com/docs/manual/reference/built-in-roles/
查看用户信息
执行下述指令查看当前数据库系统中的所有用户信息
use admin
db.system.users.find()验证用户权限
在 test 数据库中验证当前 cauchy 用户权限
use test
db.auth(cauchy, root)删除用户
use test
db.dropUser(cauchy)skynet.db.mongo 模块使用
本节主要讲解在 Skynet 框架中一些常用的 API以及如何使用相应的 API 来执行 MongoDB 的 CRUD。
前置变量、方法
host 127.0.0.1
port 27017
username cauchy
password root
authdb test
db_name testfunction create_client()return mongo.client({host host, port port,username username,password password, authdb authdb})
end auth 数据库连接认证 用法db:auth(user, pwd)
测试代码
function test_auth()local ok, err, retlocal c mongo.client({host host, port port,})local db c[db_name]db:auth(username, password)db.testcol:dropIndex(*)db.testcol:drop()ok, err, ret db.testcol:safe_insert({test_key 1});assert(ok and ret and ret.n 1, err)
end 如果注释掉认证-- db:auth(username, password)则会报错提示需要权限认证。 ensureIndex 创建索引 用法db.collection:ensureIndex({ key1 }, { option })
源码 mongo.lua 中这个 API 实际上就是创建索引
mongo_collection.ensureIndex mongo_collection.createIndex测试代码
function test_insert_with_index()local ok, err, retlocal c create_client()local db c[db_name]db.testcol:dropIndex(*)db.testcol:drop()db.testcol:ensureIndex({test_key 1}, {unique true, name test_key_index})--[[ mongoshdb.testcol.getIndexes()]]ok, err, ret db.testcol:safe_insert({test_key 1})assert(ok and ret and ret.n 1, err)ok, err, ret db.testcol:safe_insert({test_key 1})assert(ok false and string.find(err, duplicate key error))
end执行结果 find、findOne 查找符合条件的文档find 查找所有findOne 查找第一条 用法db.collection:find(query, projection)、db.collection:findOne(query, projection)projection查询结果的投影
源码next、find、findOne
local mongo_cursor {}
local cursor_meta {__index mongo_cursor,
}
------------------------------------------------------------------------------------------------------
function mongo_cursor:next()if self.__ptr nil thenerror Call hasNext firstendlocal r self.__document[self.__ptr]self.__ptr self.__ptr 1if self.__ptr #self.__document thenself.__ptr nilendreturn r
end
------------------------------------------------------------------------------------------------------
function mongo_collection:findOne(query, projection)local cursor self:find(query, projection)if cursor:hasNext() thenreturn cursor:next()endreturn nil
end
------------------------------------------------------------------------------------------------------
function mongo_collection:find(query, projection)return setmetatable( {__collection self,__query query and bson_encode(query) or empty_bson,__projection projection and bson_encode(projection) or empty_bson,__ptr nil,__data nil,__cursor nil,__document {},__flags 0,__skip 0,__limit 0,__sort empty_bson,} , cursor_meta)
end简单查看上述源码可以发现 cursor:next 返回 __document 中的内容即为实际找到的文档内容。 find 返回一张表表中有很多字段__collection、__cursor、__document 等这张表的元表是 cursor_meta而 cursor_meta 的属性 __index 是表 mongo_cursor。所以在用 find 查找符合条件的文档时返回的值应该使用 next 方法去一个个遍历获取所有的返回结果即为 __document 中的内容。 findOne 直接就是返回查找到的第一个文档如上述 return cursor:next()。 insert、safe_insert 插入一条文档 用法db.collection:insert(doc)、db.collection:safe_insert(doc)
源码
function mongo_collection:insert(doc)if doc._id nil thendoc._id bson.objectid()endself.database:send_command(insert, self.name, documents, {bson_encode(doc)})
end
------------------------------------------------------------------------------------------------------
function mongo_collection:safe_insert(doc)local r self.database:runCommand(insert, self.name, documents, {bson_encode(doc)})return werror(r)
end如上述源码safe_insert 会返回一些相关信息由 werror 返回而 insert 没有任何返回值。 delete、safe_delete 删除符合条件的一条或多条文档 用法db.collection:delete(query, single)、db.collection:safe_delete(query, single)single删除条数即limit限制
源码
function mongo_collection:delete(query, single)self.database:runCommand(delete, self.name, deletes, {bson_encode({q query,limit single and 1 or 0,})})
end
------------------------------------------------------------------------------------------------------
function mongo_collection:safe_delete(query, single)local r self.database:runCommand(delete, self.name, deletes, {bson_encode({q query,limit single and 1 or 0,})})return werror(r)
end如上述源码safe_delete 会返回一些相关信息由 werror 返回而 delete 没有任何返回值。
测试代码
function test_find_and_remove()local ok, err, retlocal c create_client()local db c[db_name]db.testcol:dropIndex(*)db.testcol:drop()local cursor db.testcol:find()assert(cursor:hasNext() false)db.testcol:ensureIndex({test_key 1}, {test_key2 -1}, {unique true, name test_index})ok, err, ret db.testcol:safe_insert({test_key 1, test_key2 1})assert(ok and ret and ret.n 1, err)cursor db.testcol:find()assert(cursor:hasNext() true)local v cursor:next()assert(v)assert(v.test_key 1)ok, err, ret db.testcol:safe_insert({test_key 1, test_key2 2})assert(ok and ret and ret.n 1, err)ok, err, ret db.testcol:safe_insert({test_key 2, test_key2 3})assert(ok and ret and ret.n 1, err)ret db.testcol:findOne({test_key2 1})assert(ret and ret.test_key2 1, err)ret db.testcol:find({test_key2 {[$gt] 0}}):sort({test_key 1}, {test_key2 -1}):skip(1):limit(1)--[[ mongoshdb.testcol.find({test_key2: {$gt: 0}}).sort({test_key: 1}, {test_key2: -1}).skip(1).limit(1)]]assert(ret:count() 3)assert(ret:count(true) 1)if ret:hasNext() thenret ret:next()endassert(ret and ret.test_key2 1)db.testcol:delete({test_key 1})db.testcol:delete({test_key 2})ret db.testcol:findOne({test_key 1})assert(ret nil)
end上述代码中有调用了sort、 skip、limit如源码所示即为 find 返回的表中__sort、__skip 、__limit字段附上了值而不是直接对数据执行排序跳转、约束等操作。
count 比较特殊会实际执行一次指令 runCommand需要参数 with_limit_and_skip。如果参数为 nil 或 false则执行会忽略 skip和 limit反之会加上。
源码sort、 skip、limit、count
-- cursor:sort { key 1 } or cursor:sort( {key1 1}, {key2 -1})
function mongo_cursor:sort(key, key_v, ...)if key_v thenlocal key_list unfold({}, key, key_v , ...)key bson_encode_order(table.unpack(key_list))endself.__sort keyreturn self
endfunction mongo_cursor:skip(amount)self.__skip amountreturn self
endfunction mongo_cursor:limit(amount)self.__limit amountreturn self
endfunction mongo_cursor:count(with_limit_and_skip)local cmd {count, self.__collection.name,query, self.__query,}if with_limit_and_skip thenlocal len #cmdcmd[len1] limitcmd[len2] self.__limitcmd[len3] skipcmd[len4] self.__skipendlocal ret self.__collection.database:runCommand(table.unpack(cmd))assert(ret and ret.ok 1)return ret.n
endupdate、safe_update 更新一条文档 用法db.collection:update(query,update,upsert,multi)、db.collection:safe_update(query,update,upsert,multi)upsert : 默认是false。如果不存在 query 对应条件的文档是 true 则插入一条新文档false 则不插入。multi : 默认是 false只更新找到的第一条记录。是 true就把按条件查出来多条记录全部更新。
示例代码
function test_update()local ok, err, rlocal c create_client()local db c[db_name]db.testcol:dropIndex(*)db.testcol:drop()db.testcol:safe_insert({test_key 1, test_key2 1})db.testcol:safe_insert({test_key 1, test_key2 2})-- ok, err, r db.testcol:safe_update({test_key2 2}, { [$set] {test_key 2} }, true, false)-- assert(ok and r and r.n 1)ok, err, r db.testcol:safe_update({test_key 1}, { [$set] {test_key2 3} }, true, true)assert(ok and r and r.n 2)
end aggregate 聚合将来自多个 doc 的 value 组合在一起并通过对分组数据进行各种操作处理返回计算后的数据结果主要用于处理数据例如统计平均值求和等。 用法db.collection:aggregate({ { [$project] {tags 1} } }, {cursor{}})param pipeline: arrayparam options: map
测试代码
function test_runcommand()local ok, err, retlocal c create_client()local db c[db_name]db.testcol:dropIndex(*)db.testcol:drop()ok, err, ret db.testcol:safe_insert({test_key 1, test_key2 1})assert(ok and ret and ret.n 1, err)ok, err, ret db.testcol:safe_insert({test_key 1, test_key2 2})assert(ok and ret and ret.n 1, err)ok, err, ret db.testcol:safe_insert({test_key 2, test_key2 3})assert(ok and ret and ret.n 1, err)local pipeline {{[$group] {_id mongo.null,test_key_total { [$sum] $test_key},test_key2_total { [$sum] $test_key2 },}}}ret db:runCommand(aggregate, testcol, pipeline, pipeline, cursor, {})assert(ret and ret.cursor.firstBatch[1].test_key_total 4)assert(ret and ret.cursor.firstBatch[1].test_key2_total 6)local res db.testcol:aggregate(pipeline, {cursor{}})assert(res and res.cursor.firstBatch[1].test_key_total 4)assert(res and res.cursor.firstBatch[1].test_key2_total 6)
end官方的 aggregate 接口手册https://www.mongodb.com/docs/manual/reference/command/aggregate/ safe_batch_insert、safe_batch_delete 批量插入和删除 用法db.collection:safe_batch_insert(docs)、db.collection:safe_batch_delete(docs)
测试代码
function test_batch_insert_delete()local ok, err, retlocal c create_client()local db c[db_name]db.testcol:dropIndex(*)db.testcol:drop()local insert_docs {}local insert_length 10for i 1, insert_length do table.insert(insert_docs, {test_key i})end db.testcol:safe_batch_insert(insert_docs)ret db.testcol:find()assert(insert_length ret:count(), test safe batch insert failed)local delete_docs {}local delete_length 5for i 1, delete_length do table.insert(delete_docs, {test_key i})end db.testcol:safe_batch_delete(delete_docs)assert(ret:count() insert_length - delete_length, test safe batch delete failed)
end 更多的 skynet.db.mongo 模块用法可以去源码阅读查看。
附上 MongoDB 7.0 Manual