转载

使用 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开发,相当于lua 5.1,需要使用lua-compat-5.2兼容lua 5.2

2、使用ngx.socket.tcp替换mongo.socket模块

3、增加了count,query,auth等方法

修改之后的代码见: lua-mongo

具体的操作MongoDB的lua代码如下:

-- lua mongo test script -- utils function string:split(sep)  local sep, fields = sep or ":", {}  local pattern = string.format("([^%s]+)", sep)  self:gsub(pattern, function(c) fields[#fields + 1] = c end)  return fields 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") -- 状态 local status_msg = "error" local status_code = 500 local message = "unknown error" local mongo_query = {["category_id"] = {["$in"] = {1,2,3,4}}, ["status"] = {["$ne"] = 2}, ["create_time"] = {["$lte"] = 1427102260}} local mongo_sort = {["create_time"] = 1} local mongo_limit = 100 local mongo_skip = 0 local mongo_fields = { ["_id"] = false } -- 涉及到时间的字段,需要使用bson转化一下 if mongo_query["create_time"] then  local create_time = mongo_query["create_time"]  local t = type(create_time)  if t == "table" then   for key, value in pairs(create_time) do    mongo_query["create_time"][key] = cbson.date(value)   end  else   mongo_query["create_time"] = cbson.date(create_time)  end end local conn = mongo.client({ host = HOST, port = PORT }) conn:set_timeout(CONN_TIMEOUT) local db = conn:getDB(DB_NAME) local reused_times = conn:get_reused_times() if reused_times == 0 then   db:auth(DB_USER, DB_PASSWD) end local col = db:getCollection(DB_COLLECTION) local result = {} -- count local count, err = col:count(mongo_query) local ok, err = conn:set_keepalive(KEEPALIVE_TIMEOUT, KEEPALIVE_SIZE) if count ~= nil then  result = count  status_code = 200  status_msg = "ok"  message = "success" end -- query local bson_obj if mongo_sort then  bson_obj = cbson.encode_order("$query", mongo_query, "$orderby", mongo_sort) else  bson_obj = cbson.encode({ ["$query"] = mongo_query }) end local results = col:query(bson_obj, mongo_fields, mongo_skip, mongo_limit) local ok, err = conn:set_keepalive(KEEPALIVE_TIMEOUT, KEEPALIVE_SIZE) if results then  for _, object in pairs(results) do   for key, value in pairs(object) do    if value == cbson.null then     object[key] = cjson.null    else     local type_name, value = cbson.type(value)     object[key] = value    end   end  end  result = results  status_code = 200  status_msg = "ok"  message = "success" end -- findOne local results = col:findOne({["id"] = 14 }) local ok, err = conn:set_keepalive(KEEPALIVE_TIMEOUT, KEEPALIVE_SIZE) if results then  for key, value in pairs(results) do   if value == cbson.null then    results[key] = cjson.null   else    local type_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) 

Over!

正文到此结束
Loading...