MongoDB(二)
一、安装MongoDB1、安装MongoDB
rpm包下载地址:http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/RPMS/
# yum localinstall -y mongo-10gen-2.4.14-mongodb_1.x86_64.rpm mongo-10gen-server-2.4.14-mongodb_1.x86_64.rpm 2、查看rpm包生成的几个重要文件
# rpm -ql mongo-10gen
/usr/bin/bsondump
/usr/bin/mongo
/usr/bin/mongodump
/usr/bin/mongoexport
/usr/bin/mongofiles
/usr/bin/mongoimport
/usr/bin/mongooplog
/usr/bin/mongoperf
/usr/bin/mongorestore
/usr/bin/mongostat
/usr/bin/mongotop
# rpm -ql mongo-10gen-server
/etc/mongod.conf
/etc/rc.d/init.d/mongod
/etc/sysconfig/mongod
/usr/bin/mongod
/usr/bin/mongos
/usr/share/man/man1/mongod.1
/usr/share/man/man1/mongos.1
/var/lib/mongo
/var/log/mongo
/var/log/mongo/mongod.log
3、初始化数据库
说明:实际使用中将存放数据的目录放在有冗余的逻辑卷上。
# mkdir /data/mongodb -p
# vim /etc/mongod.conf
dbpath=/data/mongodb
4、启动数据库
# service mongod start
Starting mongod: about to fork child process, waiting until server is ready for connections.
forked process: 4713
all output going to: /var/log/mongo/mongod.log
child process started successfully, parent exiting [确定]
# ss -tnlp |grep mongod
LISTEN 0 128 *:28017 *:* users:(("mongod",4713,11))
LISTEN 0 128 *:27017 *:* users:(("mongod",4713,9))
5、MongoDB的web接口
二、使用MongoDB
1、MongoDB与MySQL语法对比
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。
2、mongodb语法
查询colls所有数据
db.colls.find() //select * from colls 通过指定条件查询
db.colls.find({‘last_name’: ‘Smith’});//select * from colls where last_name=’Smith’ 指定多条件查询
db.colls.find( { x : 3, y : “foo” } );//select * from colls where x=3 and y=’foo’ 指定条件范围查询
db.colls.find({j: {$ne: 3}, k: {$gt: 10} });//select * from colls where j!=3 and k>10 查询不包括某内容
db.colls.find({}, {a:0});//查询除a为0外的所有数据 支持=查询,需用符号替代分别为$lt,$lte,$gt,$gte
db.colls.find({ “field” : { $gt: value } } );
db.colls.find({ “field” : { $lt: value } } );
db.colls.find({ “field” : { $gte: value } } );
db.colls.find({ “field” : { $lte: value } } );
也可对某一字段做范围查询
db.colls.find({ “field” : { $gt: value1, $lt: value2 } } ); 不等于查询用字符$ne
db.colls.find( { x : { $ne : 3 } } ); in查询用字符$in
db.colls.find( { “field” : { $in : array } } );
db.colls.find({j:{$in: }});
not in查询用字符$nin
db.colls.find({j:{$nin: }}); 取模查询用字符$mod
db.colls.find( { a : { $mod : [ 10 , 1 ] } } )// where a % 10 == 1 $all查询
db.colls.find( { a: { $all: [ 2, 3 ] } } );//指定a满足数组中任意值时 $size查询
db.colls.find( { a : { $size: 1 } } );//对对象的数量查询,此查询查询a的子对象数目为1的记录 $exists查询
db.colls.find( { a : { $exists : true } } ); // 存在a对象的数据
db.colls.find( { a : { $exists : false } } ); // 不存在a对象的数据
$type查询$type值为bsonhttp://bsonspec.org/数 据的类型值
db.colls.find( { a : { $type : 2 } } ); // 匹配a为string类型数据
db.colls.find( { a : { $type : 16 } } ); // 匹配a为int类型数据
使用正则表达式匹配
db.colls.find( { name : /acme.*corp/i } );//类似于SQL中like 内嵌对象查询
db.colls.find( { “author.name” : “joe” } ); 1.3.3版本及更高版本包含$not查询
db.colls.find( { name : { $not : /acme.*corp/i } } );
db.colls.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );
sort()排序
db.colls.find().sort( { ts : -1 } );//1为升序2为降序 limit()对限制查询数据返回个数
db.colls.find().limit(10) skip()跳过某些数据
db.colls.find().skip(10) snapshot()快照保证没有重复数据返回或对象丢失
count()统计查询对象个数
db.students.find({‘address.state’ : ‘CA’}).count();//效率较高
db.students.find({‘address.state’ : ‘CA’}).toArray().length;//效率很低
group()对查询结果分组和SQL中group by函数类似
distinct()返回不重复值
3、查询语句说明:
“db.collection.find(,)” 类似于SQL中select语句,其中相当于where子句,而相当于要选定的字段。
如果使用的find()方法中不包含,则意味着要返回对应collection的所有文档。
“db.collection.count()”方法可以统计指定collection中文档的个数。
比较运算:
$gt:挑选指定字段值大于指定值的文档,语法格式“{field: {$gt: value}}”;
$gte:挑选指定字段值大于等于指定值的文档,语法格式“{field: $gte: value}”;
$in:挑选指定字段的值位于指定数组中的文档,语法格式“{filed: {$in: [,,...]}}”;
$lt:挑选指定字段值小于指定值的文档,语法格式“{field: {$lt: value}}”;
$lte:挑选指定字段值小于等于指定值的文档,语法格式“{field: {$lte: value}}”;
$ne:挑选指定字段值不等于指定值的文档,语法格式“{filed: {$ne: value}}”;
$nin:挑选指定字段的值没有位于指定数组中或不存在的文档,语法格式“{filed: {$nin: [,...valueN]}}”;
逻辑运算:
逻辑运算一般用于连接多个选择条件,MongoDB支持的逻辑运算“Query Selector”有以下几种:
$or:或运算,语句格式“{$or: [{},{},... ,{}]}”
$and:与运算,语法格式“{$and: [{},{},... ,{}]}”
$and:非运算,语法格式“{field: {$not: {}}}”
$nor:反运算,即返回不符合所有指定条件的文档,语法格式“$nor: [{},{},.... ,{}]}”
元素查询:
如果要根据文档中是否存在某字段等条件来挑选文档,则需要用到元素运算。
$exixts:根据指定字段的存在性挑选文档,语法格式“{ field: {$exists: }}”,指定的值为“true”则返回存在指定字段的文档,“false”则返回不存在指定字段的文档。
$mod:将指定字段的值进行取模运算,并返回其余数为指定值的文档,语法格式“{field: {$mod: }}”。
$type:返回指定字段的值类型为指定类型的文档,语法格式“{field: {$type: }}”。
3、实际练习
连入数据库
# mongo
MongoDB shell version: 2.4.14
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
>
数据的插入
> show dbs
admin(empty)
local0.078125GB
> db.testcoll.insert({Name:"bols"})
> show collections
system.indexes
testcoll
> db.testcoll.insert({Name:"longls"})
> db.testcoll.find()
{ "_id" : ObjectId("5602a24111db41a96277c761"), "Name" : "bols" }
{ "_id" : ObjectId("5602a28811db41a96277c762"), "Name" : "longls" }
> show dbs
admin(empty)
local0.078125GB
test0.203125GB
查看状态:
> db.testcoll.stats()
{
"ns" : "test.testcoll",
"count" : 2,
"size" : 80,
"avgObjSize" : 40,
"storageSize" : 4096,
"numExtents" : 1,
"nindexes" : 1,
"lastExtentSize" : 4096,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 8176,
"indexSizes" : {
"_id_" : 8176
},
"ok" : 1
}
就插入了两条数据而占用了100多M的空间,说明很占用存储空间。
mongodb占用空间过大的原因,在官方的FAQ中,提到有如下几个方面:
[*] 空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、 256M那样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。
[*] 字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果 value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是最大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用 空间就小了,但这就要求在易读性与空间占用上作为权衡了。我曾建议作者把字段名作个index,每个字段名用一个字节表示,这样就不用担心字段名取多长 了。但作者的担忧也不无道理,这种索引方式需要每次查询得到结果后把索引值跟原值作一个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是 拿空间来换取时间吧。
[*] 删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。
[*] 可以定期运行db.repairDatabase()来整理记录,但这个过程会比较缓慢。
删除collections:
> db.testcoll.drop()
true
> show collections
system.indexes
> show dbs
admin(empty)
local0.078125GB
test0.203125GB
添加练习例子:
> for(i=1;i db.testcoll.find().limit(2)
{ "_id" : ObjectId("5602aa5311db41a96277c763"), "Name" : "User:1", "Age" : 1, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c764"), "Name" : "User:2", "Age" : 2, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
删除年龄为5的文档:
> db.testcoll.remove({Age:5})
> db.testcoll.find().limit(6)
{ "_id" : ObjectId("5602aa5311db41a96277c763"), "Name" : "User:1", "Age" : 1, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c764"), "Name" : "User:2", "Age" : 2, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c765"), "Name" : "User:3", "Age" : 3, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c766"), "Name" : "User:4", "Age" : 4, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c768"), "Name" : "User:6", "Age" : 6, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c769"), "Name" : "User:7", "Age" : 7, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
删除用户为User:3的文档:
> db.testcoll.remove({Name: "User:3"})
> db.testcoll.find().limit(5)
{ "_id" : ObjectId("5602aa5311db41a96277c763"), "Name" : "User:1", "Age" : 1, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c764"), "Name" : "User:2", "Age" : 2, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c766"), "Name" : "User:4", "Age" : 4, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c768"), "Name" : "User:6", "Age" : 6, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c769"), "Name" : "User:7", "Age" : 7, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
将User:4用户的年龄改为22:
> db.testcoll.update({Name: "User:4"},{$set: {Age: 22}})
> db.testcoll.find().limit(4)
{ "_id" : ObjectId("5602aa5311db41a96277c763"), "Name" : "User:1", "Age" : 1, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c764"), "Name" : "User:2", "Age" : 2, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c766"), "Name" : "User:4", "Age" : 22, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c768"), "Name" : "User:6", "Age" : 6, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
查看test库的文档数,及年龄大于97的文档:
> db.testcoll.count()
98
> db.testcoll.find({Age: {$gte :97}})
{ "_id" : ObjectId("5602aa5311db41a96277c7c3"), "Name" : "User:97", "Age" : 97, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c7c4"), "Name" : "User:98", "Age" : 98, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c7c5"), "Name" : "User:99", "Age" : 99, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c7c6"), "Name" : "User:100", "Age" : 100, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
查询年龄大于97的文档并只显示Name和Age:
> db.testcoll.find({Age: {$gte :97}},{Name:1,Age:1})
{ "_id" : ObjectId("5602aa5311db41a96277c7c3"), "Name" : "User:97", "Age" : 97 }
{ "_id" : ObjectId("5602aa5311db41a96277c7c4"), "Name" : "User:98", "Age" : 98 }
{ "_id" : ObjectId("5602aa5311db41a96277c7c5"), "Name" : "User:99", "Age" : 99 }
{ "_id" : ObjectId("5602aa5311db41a96277c7c6"), "Name" : "User:100", "Age" : 100 }
查询Age大于60并小于66的文档:
> db.testcoll.find({$and:[{Age: {$gt:60}},{Age: {$lt: 66}}]},{Name:1})
{ "_id" : ObjectId("5602aa5311db41a96277c79f"), "Name" : "User:61" }
{ "_id" : ObjectId("5602aa5311db41a96277c7a0"), "Name" : "User:62" }
{ "_id" : ObjectId("5602aa5311db41a96277c7a1"), "Name" : "User:63" }
{ "_id" : ObjectId("5602aa5311db41a96277c7a2"), "Name" : "User:64" }
{ "_id" : ObjectId("5602aa5311db41a96277c7a3"), "Name" : "User:65" }
查询包含Adress字段的文档:
> db.testcoll.find({Adress: {$exists:true}})
{ "_id" : ObjectId("5602b12411db41a96277c7c8"), "Name" : "xiyan", "Age" : 25, "Gender" : "F", "Adress" : "Chongqing,China" }
将Age大于98文档中的Gender改为M:
> db.testcoll.update({Age: {$gt:98}},{$set: {Gender: "M"}},{multi:true})
> db.testcoll.find({Age: {$gte: 98}})
{ "_id" : ObjectId("5602aa5311db41a96277c7c4"), "Name" : "User:98", "Age" : 98, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c7c5"), "Name" : "User:99", "Age" : 99, "Gender" : "M", "PreferBooks" : ["First blood","Second blood" ] }
{ "_id" : ObjectId("5602aa5311db41a96277c7c6"), "Name" : "User:100", "Age" : 100, "Gender" : "M", "PreferBooks" : ["First blood","Second blood" ] }
将Name为User:99的文档中PreferBooks项给删除:
> db.testcoll.update({Name: "User:99"},{$unset: {PreferBooks: ""}})
> db.testcoll.find({Age: {$gte: 98}})
{ "_id" : ObjectId("5602aa5311db41a96277c7c4"), "Name" : "User:98", "Age" : 98, "Gender" : "F", "PreferBooks" : ["First blood","Second blood" ] }
{ "Age" : 99, "Gender" : "M", "Name" : "User:99", "_id" : ObjectId("5602aa5311db41a96277c7c5") }
{ "_id" : ObjectId("5602aa5311db41a96277c7c6"), "Name" : "User:100", "Age" : 100, "Gender" : "M", "PreferBooks" : ["First blood","Second blood" ] }
页:
[1]