From 5b469c0a9a832908863f4a707354060cbbd3e136 Mon Sep 17 00:00:00 2001 From: Learno Date: Tue, 3 Mar 2015 16:54:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A9=E5=B1=95mongo=E5=BA=93=E5=AF=B9sort,?= =?UTF-8?q?=20skip,=20limit,=20count=E6=96=B9=E6=B3=95=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lualib/mongo.lua | 41 +++++++++++++++++++++++++++++++++++++++-- test/testmongodb.lua | 12 ++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lualib/mongo.lua b/lualib/mongo.lua index 7a8d6eb6..a1a2e11e 100644 --- a/lualib/mongo.lua +++ b/lualib/mongo.lua @@ -279,9 +279,45 @@ function mongo_collection:find(query, selector) __cursor = nil, __document = {}, __flags = 0, + __skip = 0, + __sortquery = nil, + __limit = 0, } , cursor_meta) end +function mongo_cursor:sort(key_list) + self.__sortquery = bson_encode {['$query'] = self.__query, ['$orderby'] = key_list} + return self +end + +function mongo_cursor:skip(amount) + self.__skip = amount + return self +end + +function mongo_cursor:limit(amount) + self.__limit = amount + return self +end + +function mongo_cursor:count(with_limit_and_skip) + local cmd = { + 'count', self.__collection.name, + 'query', self.__query, + } + if with_limit_and_skip then + local len = #cmd + cmd[len+1] = 'limit' + cmd[len+2] = self.__limit + cmd[len+3] = 'skip' + cmd[len+4] = self.__skip + end + local ret = self.__collection.database:runCommand(table.unpack(cmd)) + assert(ret and ret.ok == 1) + return ret.n +end + + -- collection:createIndex({username = 1}, {unique = true}) function mongo_collection:createIndex(keys, option) local name = option.name @@ -348,10 +384,11 @@ function mongo_cursor:hasNext() local sock = conn.__sock local pack if self.__data == nil then - pack = driver.query(request_id, self.__flags, self.__collection.full_name,0,0,self.__query,self.__selector) + local query = self.__sortquery or self.__query + pack = driver.query(request_id, self.__flags, self.__collection.full_name, self.__skip, -self.__limit, query, self.__selector) else if self.__cursor then - pack = driver.more(request_id, self.__collection.full_name,0,self.__cursor) + pack = driver.more(request_id, self.__collection.full_name, -self.__limit, self.__cursor) else -- no more self.__document = nil diff --git a/test/testmongodb.lua b/test/testmongodb.lua index f1fa81e0..d1fed034 100644 --- a/test/testmongodb.lua +++ b/test/testmongodb.lua @@ -43,10 +43,22 @@ function test_find_and_remove() local ret = db[db_name].testdb:safe_insert({test_key = 1}) assert(ret and ret.n == 1) + local ret = db[db_name].testdb:safe_insert({test_key = 2}) + assert(ret and ret.n == 1) + local ret = db[db_name].testdb:findOne({test_key = 1}) assert(ret and ret.test_key == 1) + local ret = db[db_name].testdb:find({test_key = {['$gt'] = 0}}):sort({test_key = -1}):skip(1):limit(1) + assert(ret:count() == 2) + assert(ret:count(true) == 1) + if ret:hasNext() then + ret = ret:next() + end + assert(ret and ret.test_key == 1) + db[db_name].testdb:delete({test_key = 1}) + db[db_name].testdb:delete({test_key = 2}) local ret = db[db_name].testdb:findOne({test_key = 1}) assert(ret == nil)