Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1280266
  • 博文数量: 79
  • 博客积分: 1959
  • 博客等级: 上尉
  • 技术积分: 2719
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-19 12:07
个人简介

樽中酒不空

文章分类

全部博文(79)

文章存档

2024年(3)

2020年(4)

2019年(1)

2017年(2)

2016年(2)

2015年(7)

2014年(11)

2013年(13)

2012年(18)

2011年(2)

2010年(16)

分类: 数据库开发技术

2010-06-23 15:33:02

提要:
  MongoDB的源码安装
  MongoDB服务器端启动运行
  MongoDB客户端程序运行
  使用官方的c++接口访问数据库


一 MongoDB的源码安装
运行平台选择红帽企业版5(相同步骤在CentOS5.4下也安装成功。)
Linux系统安装时选择比较简单,只安装了必要的开发工具,比如python2.4,gcc,g++等。
所以MongoDB的一些依赖都要手动安装上。
1 pcre:
  下载,解压,然后./configure --enable-utf8 --enable-unicode-properties --enable-pcretest-libreadline,make,make install
  提示:  pcre需要readline和ncurses,不过这两个库很常见,下载安装即可。
  pcre make时如果提示函数链接错误,直接修改Makefile,在LIBREADLINE = -lreadline 这一行加上 -lncurses

2 mozjs,下载1.7 ftp://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz
  curl -O ftp://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz
tar zxvf js-1.7.0.tar.gz
cd js/src
export CFLAGS="-DJS_C_STRINGS_ARE_UTF8"
make -f Makefile.ref
JS_DIST=/usr make -f Makefile.ref export

3 boost:
下载1.43
 安装前先:
rpm -e boost-devel-1.33.1-10.el5.i386

查找usr/include, usr/lib, 删掉所有旧版本boost

然后,
./bootstrap.sh
./bjam -sHAVE_ICU=1
(官方是./bjam -sHAVE_ICU=1 threading=multi --with-program_options --with-filesystem --with-date_time --with-thread)
编译完成后,
把新安装的boost路径放到PATH,ldconfig
或:cp -Rf boost /usr/local/include/
    cp ./stage/*.* /usr/local/lib/
我用后面cp的方法。

4 安装 scons

下载 scons-2.0.0.final.0.tar.gz
执行python setup.py install
系统带的python是2.4,不需要更新到2.5或2.6。更新后需要修改ln,否则可能会出错。

5 编译mongoDB

先编译:scons all
再安装:scons --prefix=/usr/local install
(我把从源码编译出的所有第三方库都放在/usr/local/下)。
编译过程中常见的错误有:找不到 jsapi.h, boost 多线程库函数链接问题,python的hashlib找不到等等。如果环境和我差不多的话,按上面操作是没问题的。实在不行,我个人是在虚拟机上装了多次Linux系统,最后试出来的经验。
最后,切记,python升级后,一定要把原来的2.4和升级后的2.5或2.6链接做好,否则,这里出问题最多。

1 mongoDB服务器端运行:
启动:nohup mongod&
如果提示没有/data/db目录,先创建,再执行。

2 mongoDB客户端运行:
mongo
然后在命令行输入指令执行。


最重要的是通过c++接口来操作数据库,在first.cpp这个例子上修改:

先生成一个makefile:
C_FLAGS= -Wall -Wpointer-arith -O3 -pipe -g -D_REENTRANT -D_GUN_SOURCE -D_NET_LOG
CXX= g++
LIB_DIR=.
INC= -I/usr/local/include -I/usr/local/include/boost -I/usr/local/include/mongo -I.

LIB= -L/usr/local/lib -lmongoclient -lboost_filesystem -lboost_system -lboost_thread -lboost_regex

SOURCES_FILES_CPP=$(wildcard *.cpp)
EXE_FILE=$(SOURCES_FILES_CPP:%.cpp=%)

$(EXE_FILE):
    for E in $(EXE_FILE) ; \
          do \
            echo "$(CXX) -g -o2 -o $$E $$E.cpp $(C_FLAGS) $(INC) $(LIB)"; \
            $(CXX) -g -o2 -o $$E $$E.cpp $(C_FLAGS) $(INC) $(LIB);\
          done
#    for E in $(EXE_FILE) ; \
        do \
          echo "strip ./$$E ";\
          strip ./$$E ;\
        done
all:$(EXE_FILE)
    @echo "$(EXE_FILE)"
clean:
    rm -f $(EXE_FILE)

程序源码:
//first.cpp
#include "dbclient.h"
using namespace std;
using namespace mongo;
DBClientConnection conn;
int main()
{
   const char *port = "27017";
   string errmsg;
     
   if ( ! conn.connect( string( "127.0.0.1:" ) + port , errmsg ) )
     {
       cout << "couldn't connect : " << errmsg << endl;
       return -1;
   }
   cout << "connect success " << endl;
   return 0;
}

编译,运行,可以看到运行结果。(mongod在之前先运行起来。)
这是connect功能。

下面是insert功能:

void InsertMsg(uint32_t srcID, uint32_t destID, string& msg, uint32_t time)
{
      BSONObjBuilder obj;
    obj.append( "srcID" , srcID );
    obj.append( "destID" ,destID);
      obj.append( "msg" ,   msg.c_str());
    obj.append( "posttime" , time);

    conn.insert( "test.testmsg" , obj.obj() );
}
在main()中调用 InsertMsg(1001, 1002, "test msg", 1100110010);
运行后,执行phpmoadmin,应该可以看到test库下面的testmsg表中有一条记录。

更简单一点的insert方法:
for( uint32_t i = 0; i < 1000001; ++i )
  conn.insert( "test.test1", BSON( "_id" << i << "b" << i ) );
执行结束,会看到表中插入了1百万零一条记录。用time()得到两个时间相减,在我的机器上运行时间为27秒。
在前台能看到1百万条记录时刷新了几次页面才看到的。

删除非常简单,
conn.remove( "test.test1", BSONObj() ); //删掉表内所有记录。
conn.remove( ns, BSON( "_id" << 99 );   //删掉_id为99的这条记录。

//条件删
char qbuf[256];
sprintf(qbuf, "this._id >= 50 && this._id <= 90");
Query q = Query("{}").where(qbuf);
conn.remove( ns, q); //删掉 50-90间的一组记录。可以根据sql where设置条件。
上面,ns是字符串变量,表示数据库名。
Query("{}")看起来比较怪,是封装的JSON格式。如果不了解可以参考一下相关文档。如果不想看,记住这种写法就是了。

删掉一个表:
conn.dropCollection("test.test2");

更新符合条件记录:
mongodb_.update("test.webuser", QUERY("web_uid" << 1001), BSON("status"<<1));

更新所有记录:
mongodb_.update("test.webuser",  Query("{}"), BSON("status" << 1));

计数:
cout<
查一条记录:
BSONObj res = mongodb_.findOne("test.test", QUERY("_id"<<1001));
if (res.isEmpty())
{
//没找到
}
else
{
  uint32_t = res.getIntField("_id");
  string str = res.getStringField("name");//假设有name这个字段,保存字符串数据
}

查多条记录,最多返回100条,保存到vector中:
auto_ptr cursor = mongodb_.query( "test.message", BSON("srcID"<<1001), 100);
    while (cursor->more())
    {
        BSONObj obj = cursor->next();
        WEB_MSG tmp;
        uint32_t cid = obj.getIntField("clientid");
        tmp.dwSendUID = cid;
        tmp.msg = obj.getStringField("message");
        tmp.time = obj.getStringField("posttime");
       
        list.push_back(tmp);
    }

取最大值:
uint32_t maxid = 0;
    Query query;
    auto_ptr cursor = mongodb_.query("test.webuser" , query.sort(BSON("web_uid" << -1)), 1);
    if (cursor->more())
    {
        BSONObj obj = cursor->next();
        maxid = obj.getIntField("web_uid");
    }

//取最小值
auto_ptr cursor = mongodb_.query("test.webuser" , query.sort(BSON("web_uid" << -1)), 1);

注:sort中,-1表示降序排列,1表示升,所以,用-1排序取第一条记录,就是最大值。反之,就是最小值。

上面例子同时也说明排序的用法。

待续



阅读(7730) | 评论(2) | 转发(0) |
0

上一篇:没有了

下一篇:lighttpd.conf

给主人留下些什么吧!~~

sxcong2010-08-25 11:16:54

boost我是按缺省来编译的,自动就出了mt 我以前也碰到过总提示找不到mt,可能是一些老版本的影响了。完全删掉老版本的,再编译安装新的。可以find一下,然后rm掉。包括include和lib下所有的。

chinaunix网友2010-08-11 15:00:19

您好。我想问下怎么编译出libboost_thread-mt 我编译出来的只有libboost_thread。。。。