MongoDB学习笔记
Centos 安装 mongodb
yum 安装
已按照 mongodb 4.4版本为例,官方说明文档:https://www.mongodb.com/docs/v4.4/tutorial/install-mongodb-on-red-hat/
配置
sudo yum list |grep mongodb-org
如果 yum 找不到mongodb-org 就需要配置repo
vim /etc/yum.repos.d/mongodb-org-4.4.repo
内容如下:
[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc
注:$releasever换成 对应Centos对应的版本号,例如Centos7 就换成7: https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.4/x86_64/
安装
sudo yum install -y mongodb-org
启动
sudo systemctl start mongod
mongo的 配置文件在/etc/mongod.conf
数据默认存储在/var/lib/mongo
修改数据存储位置
首先 停下 mongod
sudo systemctl stop mongod
将数据移动指定目录
cp -rp /var/lib/mongo /data/mongo
注:mongod访问的目录的user和group是mongod:mongod, cp -p 同时复制源文件的修改时间和访问权限
删除mongod.lock
启动mongod
sudo systemctl start mongod
编译 MongoDB C Driver
git clone https://github.com/mongodb/mongo-c-driver.git
cd mongo-c-driver
cmake .
make
make install
默认mongo-c-driver install 在/usr/local/include 和 /usr/lib64
可以 cmake 用-DCMAKE_INSTALL_PREFIX 指定install 的目录
对于线上项目都是要使用引用静态库而不是动态库,然而使用静态库编译时,依赖openssl的静态库,随便找了一个openssl静态库发现链接有问题:
dep/mongo//lib64/libmongoc-static-1.0.a(mongoc-stream-tls-openssl.c.o): In function `mongoc_stream_tls_openssl_new':
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c:788: undefined reference to `X509_VERIFY_PARAM_set_hostflags'
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c:792: undefined reference to `X509_VERIFY_PARAM_set1_ip_asc'
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c:794: undefined reference to `X509_VERIFY_PARAM_set1_host'
dep/mongo//lib64/libmongoc-static-1.0.a(mongoc-openssl.c.o): In function `_mongoc_openssl_check_peer_hostname':
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-openssl.c:212: undefined reference to `X509_check_host'
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-openssl.c:213: undefined reference to `X509_check_ip_asc'
dep/mongo//lib64/libmongoc-static-1.0.a(mongoc-compression.c.o): In function `mongoc_uncompress':
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-compression.c:178: undefined reference to `uncompress'
dep/mongo//lib64/libmongoc-static-1.0.a(mongoc-compression.c.o): In function `mongoc_compress':
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-compression.c:252: undefined reference to `compress2'
dep/mongo//lib64/libmongoc-static-1.0.a(mongoc-compression.c.o): In function `mongoc_compressor_max_compressed_length':
/data/home/user00/env/mongo-c-driver-1.23.1/src/libmongoc/src/mongoc/mongoc-compression.c:51: undefined reference to `compressBound'
collect2: error: ld returned 1 exit status
make[2]: *** [test] Error 1
make[1]: *** [CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2
我明明引用了openssl静态库为什么还有链接错误?
查了好多文档终于找到 旧版本libmongoc 关于 openssl依赖的说明 http://mongoc.org/libmongoc/1.12.0/mongoc_ssl_opt_t.html
openssl每个版本差异都很大,不止大版本,每个小版本都有差异, libmongoc在编译时可以通过-DOPENSSL_ROOT_DIR 指定openssl执行程序的所在目录, 编译时会 执行 openssl version来获取 openssl的版本,如果没有指定-DOPENSSL_ROOT_DIR 就是系统当前默认的openssl的版本
编译和使用libmongc静态库步骤
- 首先下载指定版本openssl
这里下载的是openssl-1.0.2k, 地址https://ftp.openssl.org/source/old/1.0.2/openssl-1.0.2k.tar.gz
编译
cd openssl-1.0.2k
./config --prefix=/path/openssl ## prefix是openssl install目录
make
make install
- 编译libmongoc
wget https://github.com/mongodb/mongo-c-driver/releases/download/1.23.1/mongo-c-driver-1.23.1.tar.gz
tar xzf mongo-c-driver-1.23.1.tar.gz
cd mongo-c-driver-1.23.1
cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DCMAKE_INSTALL_PREFIX=/path/libmongoc -DOPENSSL_ROOT_DIR=/path/openssl/openssl
make
make install
编译好后有两个静态库libbson-static-1.0.a和libmongoc-static-1.0.a
- 使用libmongc 静态库
在编译程序时使用 libmongoc静态库还需要 依赖 libz.a,pthread,rt,dl和resolv
Schema Validation使用
对int类型插入时报Document failed validation
在学习使用Schema Validation时,自己用 JavaScript定义了如下Validation
db.createCollection("TestDB")
db.runCommand( { collMod: "TestDB",
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "Uin"],
properties: {
Uin: {
bsonType: "int",
description: "must be a int and is required"
}
}
}
},
validationLevel: "strict"
} )
但是在插入时报错
load("mongodb_table_create.js")
db.TestDB.insertOne({name: 10})
WriteError({
"index" : 0,
"code" : 121,
"errmsg" : "Document failed validation",
"op" : {
"_id" : ObjectId("63a2b0deb3be8b1184412156"),
"name" : 10
}
}) :
WriteError({
"index" : 0,
"code" : 121,
"errmsg" : "Document failed validation",
"op" : {
"_id" : ObjectId("63a2b0deb3be8b1184412156"),
"name" : 10
}
})
WriteError@src/mongo/shell/bulk_api.js:458:48
mergeBatchResults@src/mongo/shell/bulk_api.js:855:49
executeBatch@src/mongo/shell/bulk_api.js:919:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1163:21
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:264:9
@(shell):1:1
查资料终于知道MongoDB Shell模式, 数字只有Number类型,默认是Double,所以导致校验不通过,用NumberInt() 指定类型
> db.TestDB.insertOne({Uin: NumberInt(10)})
{
"acknowledged" : true,
"insertedId" : ObjectId("63a2b2cdb3be8b1184412159")
}
终于插入成功
其余类型有
- NumberInt:32位整数
- NumberDecimal:64位浮点数
- NumberLong: 64位整数