Lua 操作 MongoDB 数据库实例
最近有个工作是使用Nginx+Lua实现一个操作MongoDB数据库的API,主要实现其count和query功能。之前没有写过Lua,于是也就勉强着上手,在cloudwu的lua-mongo的基础上实现了操作MongoDB的API。
cloudwu的lua-mongo驱动实现了连接Mongo,进行find和findOne等基本操作的功能,所以在lua-mongo的基础上增加了count和query等方法。修改的具体内容如下:
1、API基于luajit-2.0开发,相当于lua5.1,需要使用lua-compat-5.2兼容lua5.2
2、使用ngx.socket.tcp替换mongo.socket模块
3、增加了count,query,auth等方法
修改之后的代码见:lua-mongo
具体的操作MongoDB的lua代码如下:
--luamongotestscript
--utils
functionstring:split(sep)
localsep,fields=sepor":",{}
localpattern=string.format("([^%s]+)",sep)
self:gsub(pattern,function(c)fields[#fields+1]=cend)
returnfields
end
--常量
HOST="127.0.0.1"
PORT=27017
KEEPALIVE_TIMEOUT=60000
KEEPALIVE_SIZE=100
CONN_TIMEOUT=3000
DB_USER="user"
DB_PASSWD="password"
DB_NAME="blog"
DB_COLLECTION="article"
--引用
mongo=require("mongo")
cjson=require("cjson.safe")
cbson=require("bson")
--状态
localstatus_msg="error"
localstatus_code=500
localmessage="unknownerror"
localmongo_query={["category_id"]={["$in"]={1,2,3,4}},["status"]={["$ne"]=2},["create_time"]={["$lte"]=1427102260}}
localmongo_sort={["create_time"]=1}
localmongo_limit=100
localmongo_skip=0
localmongo_fields={["_id"]=false}
--涉及到时间的字段,需要使用bson转化一下
ifmongo_query["create_time"]then
localcreate_time=mongo_query["create_time"]
localt=type(create_time)
ift=="table"then
forkey,valueinpairs(create_time)do
mongo_query["create_time"][key]=cbson.date(value)
end
else
mongo_query["create_time"]=cbson.date(create_time)
end
end
localconn=mongo.client({host=HOST,port=PORT})
conn:set_timeout(CONN_TIMEOUT)
localdb=conn:getDB(DB_NAME)
localreused_times=conn:get_reused_times()
ifreused_times==0then
db:auth(DB_USER,DB_PASSWD)
end
localcol=db:getCollection(DB_COLLECTION)
localresult={}
--count
localcount,err=col:count(mongo_query)
localok,err=conn:set_keepalive(KEEPALIVE_TIMEOUT,KEEPALIVE_SIZE)
ifcount~=nilthen
result=count
status_code=200
status_msg="ok"
message="success"
end
--query
localbson_obj
ifmongo_sortthen
bson_obj=cbson.encode_order("$query",mongo_query,"$orderby",mongo_sort)
else
bson_obj=cbson.encode({["$query"]=mongo_query})
end
localresults=col:query(bson_obj,mongo_fields,mongo_skip,mongo_limit)
localok,err=conn:set_keepalive(KEEPALIVE_TIMEOUT,KEEPALIVE_SIZE)
ifresultsthen
for_,objectinpairs(results)do
forkey,valueinpairs(object)do
ifvalue==cbson.nullthen
object[key]=cjson.null
else
localtype_name,value=cbson.type(value)
object[key]=value
end
end
end
result=results
status_code=200
status_msg="ok"
message="success"
end
--findOne
localresults=col:findOne({["id"]=14})
localok,err=conn:set_keepalive(KEEPALIVE_TIMEOUT,KEEPALIVE_SIZE)
ifresultsthen
forkey,valueinpairs(results)do
ifvalue==cbson.nullthen
results[key]=cjson.null
else
localtype_name,value=cbson.type(value)
results[key]=value
end
end
result=results
status_code=200
status_msg="ok"
message="success"
end
ngx.status=status_code
json_out=cjson.encode({status=status_msg,message=message,data=result})
ngx.header["Content-Length"]=json_out:len()
ngx.print(json_out)