{name:"MongoDB", type:"NoSQL"}


####关于NoSQL

1.什么是NoSQL


NoSQL,指非关系型的数据库。No Relational, Not only SQL.


2.为什么要使用NoSQL(http://robbin.iteye.com/blog/524977  )


对数据库的“三高”需求:

 1.高并发读写

 2.对海量数据的高效率读写

 3.高扩展性和高可用性


关系型数据库的特性地位下降:

 1.事务一致性

 2.读写实时性

 3.复杂SQL,特别是多表关联查询


对自己来说学习的目的主要是跟风,囧,很多招聘信息都要求熟悉MongoDB,个人的项目也无法体会到上面所说的优势,也体会不出关系型数据库的劣势,一个sqlite就可以让我的项目跑的风吼。不过,趁着年轻,多学一点。


####MongoDB简单操作(文档:http://cn.docs.mongodb.org/manual/  )


######在Ubuntu上安装MongoDB:


1.`sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10`


2.`echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" >> /etc/apt/sources.list.d/10gen.list`


3.`sudo apt-get update`


4.`apt-get install mongodb-10gen`


配置文件:/etc/mongodb.conf


默认数据文件位置:/var/lib/mongodb


默认日志文件位置:/var/log/mongodb


默认监听端口:27017


HTTP服务端口:监听端口+1000(http://localhost:28017)


mongodb的简单操作_mongodb 数据库


默认web接口是不能使用里面的功能的,使用web接口要先建数据库目录,修改对象操作权限,再用对应参数如:--rest启动mongod


ashin@linux:~$ sudo mkdir -p /data/db
ashin@linux:~$ sudo chmod 777 /data/db
ashin@linux:~$ mongod --rest



######开启与停止服务:


开启:`sudo service mongodb start`


停止:`sudo service mongodb stop`


重启:`sudo service mongodb restart`


运行javascript shell:`mongo` (help命令可以查看帮助信息)


mongodb的简单操作_mongodb 数据库_02


MongoDB用文档保存数据(键/值):{"name":"ashin"}


键不能含有\0,它表示键的结尾,.和$还有_均为保留符号。


多个文档组成集合(集合类似于表,文档类似于行),多个集合组成数据库。


进入shell默认连接的是test数据库,使用db命令可以查看当前正在使用的数据库,use DATABASENAME可以切换使用的数据库。使用show collections可以查看当前数据库有哪些集合。文档可以套嵌,值可以为数组,用{'key':[v1,v2,v3]}表示。


######简单CRUD:


> db    //显示当前连接的数据库
test
> show collections  //显示数据库中所有集合
system.indexes
test
things
> birthday = {'year':1992, 'month':12, 'day':26}    //创建文档
{ "year" : 1992, "month" : 12, "day" : 26 }
> db.ak.insert(birthday)    //把文档加入到ak集合中,ak集合在数据库中被创建
> show collections
ak
system.indexes
test
things
> db.ak.find()  //查询集合中所有文档,Id的值由时间戳+机器+PID+计数器组成。
{ "_id" : ObjectId("51518c97862ecf1b9f562459"), "year" : 1992, "month" : 12, "day" : 26 }
> birthday.name="dog"
dog
> db.ak.update({'year':1992}, birthday) //更新修改文档
> db.ak.find()
{ "_id" : ObjectId("51518c97862ecf1b9f562459"), "year" : 1992, "month" : 12, "day" : 26, "name" : "dog" }
> db.ak.remove({"name":"dog"})  //删除文档
> db.ak.find()
>
> dog={'sex':'F'}
{ "sex" : "F" }
> dog.birthday = birthday
{ "year" : 1992, "month" : 12, "day" : 26, "name" : "dog" }
> dog   //套嵌文档
{
    "sex" : "F",
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    }
}
> dog.food = ['shit', 'maidong']    //使用数组
[ "shit", "maidong" ]
> dog.today = new Date()    //使用日期
ISODate("2013-03-26T12:17:17.045Z")
> dog
{
    "sex" : "F",
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong"
    ],
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
>


######更新文档:


$inc:对某个键的值加上指定的数

> db.ak.insert(dog)
> db.ak.update({"birthday.year":1992}, {"$inc":{"birthday.day":2}})
> db.ak.findOne()
{
    "_id" : ObjectId("5151959f862ecf1b9f56245a"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 28, //26+2
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}



$set:指定一个键的值,不存在则创建它


$unset:删除某个键


> db.ak.findOne({"birthday.day":28})
{
    "_id" : ObjectId("5151959f862ecf1b9f56245a"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 28,
        "name" : "dog"
    },
    "day" : 2,  //birthday.day写成了day造成的
    "food" : [
        "shit",
        "maidong"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> db.ak.update({"birthday.day":28}, {"$set":{"name":"cookie"}}) //添加/修改键的值
> db.ak.findOne({"birthday.day":28})
{
    "_id" : ObjectId("5151959f862ecf1b9f56245a"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 28,
        "name" : "dog"
    },
    "day" : 2,
    "food" : [
        "shit",
        "maidong"
    ],
    "name" : "cookie",
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> db.ak.update({"birthday.day":28}, {"$unset":{"day":1}})   //删除指定键
> db.ak.findOne({"birthday.day":28})
{
    "_id" : ObjectId("5151959f862ecf1b9f56245a"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 28,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong"
    ],
    "name" : "cookie",
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
>


$push:增加到数组


$ne:不等于,不含有


> db.ak.update({"food" : {"$ne":"egg"}}, {"$push":{"food":"wow"}})  //在food中不包含egg的文档中向food中加入wow
> db.ak.find()
{ "_id" : ObjectId("5151959f862ecf1b9f56245a"), "birthday" : { "year" : 1992, "month" : 12, "day" : 28, "name" : "dog" }, "food" : [    "shit",     "maidong",  "moliqingcha",  "moliqingcha",  "maijie",   "maijie",   "egg" ], "name" : "cookie", "sex" : "F", "today" : ISODate("2013-03-26T12:17:17.045Z") }
{ "_id" : ObjectId("51519644862ecf1b9f56245b"), "birthday" : { "year" : 1992, "month" : 12, "day" : 26, "name" : "dog" }, "food" : [ "shit", "maidong", "maijie", "maijie", "wahaha", "wahaha", "wow" ], "sex" : "F", "today" : ISODate("2013-03-26T12:17:17.045Z") }
>


$addToSet:添加到集合,确保不重复


> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$addToSet":{"food":"pizza"}})    //添加到set
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "maijie",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$addToSet":{"food":"pizza"}} )   //再次添加不会被添加
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "maijie",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
>


$each:[]:对数组中每个元素执行前面的操作


> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$addToSet":{"food":["pizza1","pizza2"]}} )   //为food添加一个数组
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "maijie",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza",
        [
            "pizza1",
            "pizza2"
        ]
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$addToSet":{"food":{"$each":["pizza1","pizza2"]}}} ) //$each将每个值添加到food数组中
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "maijie",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza",
        [
            "pizza1",
            "pizza2"
        ],
        "pizza1",
        "pizza2"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
>


$pop:删除数组任意一端的元素


> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$pop":{"food":1}} )  //删除food的最后一个元素
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "maijie",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza",
        [
            "pizza1",
            "pizza2"
        ],
        "pizza1"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$pop":{"food":-1}} ) //删除food的第一个元素
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "maidong",
        "maijie",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza",
        [
            "pizza1",
            "pizza2"
        ],
        "pizza1"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
>


数组下标定位


> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$set":{"food.1":"maijie2"}}) //修改food的第二个元素
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "maidong",
        "maijie2",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza",
        [
            "pizza1",
            "pizza2"
        ],
        "pizza1"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> db.ak.update({"_id":ObjectId("51519644862ecf1b9f56245b")}, {"$set":{"food.7.0":"pizza0"}})    //修改food第8个元素的第一个值
> db.ak.findOne({"_id":ObjectId("51519644862ecf1b9f56245b")})
{
    "_id" : ObjectId("51519644862ecf1b9f56245b"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 26,
        "name" : "dog"
    },
    "food" : [
        "maidong",
        "maijie2",
        "maijie",
        "wahaha",
        "wahaha",
        "wow",
        "pizza",
        [
            "pizza0",
            "pizza2"
        ],
        "pizza1"
    ],
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
>


upsert:update函数第三个参数指定为true表示upsert,即如果要更新的文档存在则正常更新,不存在就新创建。


> db.ak.update({"birthday.day":29}, {"$inc":{"day":1}}) //普通update不存在的文档不会有变化
> db.ak.find()
{ "_id" : ObjectId("5151959f862ecf1b9f56245a"), "birthday" : { "year" : 1992, "month" : 12, "day" : 28, "name" : "dog" }, "food" : [    "shit",     "maidong",  "moliqingcha",  "moliqingcha",  "maijie",   "maijie",   "egg" ], "name" : "cookie", "sex" : "F", "today" : ISODate("2013-03-26T12:17:17.045Z") }
{ "_id" : ObjectId("51519644862ecf1b9f56245b"), "birthday" : { "year" : 1992, "month" : 12, "day" : 26, "name" : "dog" }, "food" : [    "maidong",  "maijie2",  "maijie",   "wahaha",   "wahaha",   "wow",  "pizza",    [   "pizza0",   "pizza2" ],     "pizza1" ], "sex" : "F", "today" : ISODate("2013-03-26T12:17:17.045Z") }
> db.ak.update({"birthday.day":29}, {"$inc":{"day":1}}, true)   //upsert更新则会创建新文档
> db.ak.find()
{ "_id" : ObjectId("5151959f862ecf1b9f56245a"), "birthday" : { "year" : 1992, "month" : 12, "day" : 28, "name" : "dog" }, "food" : [    "shit",     "maidong",  "moliqingcha",  "moliqingcha",  "maijie",   "maijie",   "egg" ], "name" : "cookie", "sex" : "F", "today" : ISODate("2013-03-26T12:17:17.045Z") }
{ "_id" : ObjectId("51519644862ecf1b9f56245b"), "birthday" : { "year" : 1992, "month" : 12, "day" : 26, "name" : "dog" }, "food" : [    "maidong",  "maijie2",  "maijie",   "wahaha",   "wahaha",   "wow",  "pizza",    [   "pizza0",   "pizza2" ],     "pizza1" ], "sex" : "F", "today" : ISODate("2013-03-26T12:17:17.045Z") }
{ "_id" : ObjectId("51525958265b2c47d47147d3"), "birthday" : { "day" : 29 }, "day" : 1 }
>


save:文档不存在则插入,存在就修改


> dog=db.ak.findOne()
{
    "_id" : ObjectId("5151959f862ecf1b9f56245a"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 28,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "moliqingcha",
        "moliqingcha",
        "maijie",
        "maijie",
        "egg"
    ],
    "name" : "cookie",
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z")
}
> dog.color = "gold"
gold
> db.ak.save(dog)
> dog=db.ak.findOne()
{
    "_id" : ObjectId("5151959f862ecf1b9f56245a"),
    "birthday" : {
        "year" : 1992,
        "month" : 12,
        "day" : 28,
        "name" : "dog"
    },
    "food" : [
        "shit",
        "maidong",
        "moliqingcha",
        "moliqingcha",
        "maijie",
        "maijie",
        "egg"
    ],
    "name" : "cookie",
    "sex" : "F",
    "today" : ISODate("2013-03-26T12:17:17.045Z"),
    "color" : "gold"
}
>


更新多个文档:


默认更新只对符合匹配的第一个文档执行操作,要修改所有符合匹配的文档进行操作需要设置update的第四个参数为true


> db.things.find()
{ "_id" : ObjectId("51512cf4c3bb8082f1b65193"), "x" : 4, "j" : 1 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "x" : 4, "j" : 2 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "x" : 4, "j" : 3 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "x" : 4, "j" : 5 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "x" : 4, "j" : 6 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "x" : 4, "j" : 7 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "x" : 4, "j" : 8 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "x" : 4, "j" : 9 }
> db.things.update({"x":4}, {"$set":{"k":0}})
> db.things.find()
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "x" : 4, "j" : 2 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "x" : 4, "j" : 3 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "x" : 4, "j" : 5 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "x" : 4, "j" : 6 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "x" : 4, "j" : 7 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "x" : 4, "j" : 8 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "x" : 4, "j" : 9 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65193"), "j" : 1, "k" : 0, "x" : 4 } //只更新了j=1
> db.things.update({"x":4}, {"$set":{"k":0}}, false, true)
> db.things.find()  //全部更新
{ "_id" : ObjectId("51512cf4c3bb8082f1b65193"), "j" : 1, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "j" : 9, "k" : 0, "x" : 4 }
>


更新并返回文档:


普通的update更新后不会有返回值,可以通过findAndModify命令来做


> db.runCommand({"findAndModify":"things",  "query":{"x":4},  "sort":{"j":-1}, "update":{"$inc":{"k":1}}})
{
    "lastErrorObject" : {
        "updatedExisting" : true,
        "n" : 1,
        "connectionId" : 5,
        "err" : null,
        "ok" : 1
    },
    "value" : {
        "_id" : ObjectId("51512cf4c3bb8082f1b6519b"),
        "j" : 9,
        "k" : 0,
        "x" : 4
    },
    "ok" : 1
}
> db.things.find()
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "j" : 9, "k" : 1, "x" : 4 }
> db.runCommand({"findAndModify":"things",  "query":{"x":4},  "sort":{"j":-1}, "update":{"$inc":{"k":1}}}).value
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "j" : 9, "k" : 1, "x" : 4 }
> db.things.find()
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "j" : 9, "k" : 2, "x" : 4 }
> db.runCommand({"findAndModify":"things",  "query":{"k":2},  "sort":{"j":1}, "remove":true}).value
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519b"), "j" : 9, "k" : 2, "x" : 4 }
> db.things.find()
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
>



######查询


find():默认传递{}参数,{}匹配集合的全部内容


find({}, {'key1':1, "key2":1}):只返回第二个参数指定的键,_id总是被返回


> db.things.find({}, {'k':1})
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "k" : 0 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "k" : 0 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "k" : 0 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "k" : 0 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "k" : 0 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "k" : 0 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "k" : 0 }
> db.things.find({}, {'k':1, '_id':0})
{ "k" : 0 }
{ "k" : 0 }
{ "k" : 0 }
{ "k" : 0 }
{ "k" : 0 }
{ "k" : 0 }
{ "k" : 0 }


查询条件:


"$lt", "$lte", "$gt", "$gte", "$ne", "$in", "$nin", "$or", "$not", "$mod"


> db.things.find({"j":{"$gte":3, "$lte":7}})
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
>
> db.things.find({"j":{"$in":[2,4,6]}})
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
> db.things.find({"j":{"$nin":[2,4,6]}})
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
> db.things.find({"j":{"$mod":[4,3]}})  //将查询的值除以第一个给定值,余数为第二个给定值则返回结果
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
> db.things.find({"j":{"$not":{"$mod":[4,3]}}})
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
>


正则表达式:


> db.things.find()
{ "_id" : ObjectId("51526f5af1085f80823f7344"), "j" : "hello" }
{ "_id" : ObjectId("515270a7f1085f80823f7346"), "j" : "1hello" }
> db.things.find({"j":/hello/})
{ "_id" : ObjectId("51526f5af1085f80823f7344"), "j" : "hello" }
{ "_id" : ObjectId("515270a7f1085f80823f7346"), "j" : "1hello" }
> db.things.find({"j":/^hello/})
{ "_id" : ObjectId("51526f5af1085f80823f7344"), "j" : "hello" }
>


查询数组:


> db.array.insert({'a':[1,2,3]})
> db.array.insert({'a':[2,3,4]})
> db.array.insert({'a':[2,3,1]})
> db.array.find({"a":[2, 3]})
> db.array.find({"a":{"$all":[2, 3]}})  //  通过多个元素来匹配数组必须用$all
{ "_id" : ObjectId("515272d9f1085f80823f7349"), "a" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("515272dff1085f80823f734a"), "a" : [ 2, 3, 4 ] }
{ "_id" : ObjectId("515272e2f1085f80823f734b"), "a" : [ 2, 3, 1 ] }
> db.array.find({"a":[1, 2,3]}) //准确匹配,与位置有关
{ "_id" : ObjectId("515272d9f1085f80823f7349"), "a" : [ 1, 2, 3 ] }
> db.array.find({"a":[2,1,3rray.find({},{"a":{"$slice":2}}) //返回前2个元素
{ "_id" : ObjectId("515272d9f1085f80823f7349"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("515272dff1085f80823f734a"), "a" : [ 2, 3 ] }
{ "_id" : ObjectId("515272e2f1085f80823f734b"), "a" : [ 2, 3 ] }
> db.array.find({},{"a":{"$slice":-2}}) //返回后2个元素
{ "_id" : ObjectId("515272d9f1085f80823f7349"), "a" : [ 2, 3 ] }
{ "_id" : ObjectId("515272dff1085f80823f734a"), "a" : [ 3, 4 ] }
{ "_id" : ObjectId("515272e2f1085f80823f734b"), "a" : [ 3, 1 ] }
> db.array.find({},{"a":{"$slice":[0,2]}})  //返回第1个到第2个元素
{ "_id" : ObjectId("515272d9f1085f80823f7349"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("515272dff1085f80823f734a"), "a" : [ 2, 3 ] }
{ "_id" : ObjectId("515272e2f1085f80823f734b"), "a" : [ 2, 3 ] }


$where执行任意javascript作为查询:


> db.things.find({"$where":function(){
... for (i in this){
...   for (j in this){
...     if (i!=j && this[i] == this[j]){    //查找键不同但值相同的元素
...       return true;
...     }
...   }
... }
... }})
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
>


游标:


> var c = db.things.find(); //必须用var声明
> c.hasNext()
true
> while (c.hasNext()){
...   printjson(c.next())
... }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51526f5af1085f80823f7344"), "j" : "hello" }
{ "_id" : ObjectId("515270a7f1085f80823f7346"), "j" : "1hello" }
> db.things.find().limit(2) //指定返回个数上限
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
> db.things.find().skip(2)  //略过指定个数
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51526f5af1085f80823f7344"), "j" : "hello" }
{ "_id" : ObjectId("515270a7f1085f80823f7346"), "j" : "1hello" }
> db.things.find().sort({'j':-1})   //1升序,-1降序
{ "_id" : ObjectId("51526f5af1085f80823f7344"), "j" : "hello" }
{ "_id" : ObjectId("515270a7f1085f80823f7346"), "j" : "1hello" }
{ "_id" : ObjectId("51512cf4c3bb8082f1b6519a"), "j" : 8, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65199"), "j" : 7, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65198"), "j" : 6, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65197"), "j" : 5, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65196"), "j" : 4, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65195"), "j" : 3, "k" : 0, "x" : 4 }
{ "_id" : ObjectId("51512cf4c3bb8082f1b65194"), "j" : 2, "k" : 0, "x" : 4 }
>


聚合:


> db.array.find()
{ "_id" : ObjectId("515272d9f1085f80823f7349"), "a" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("515272dff1085f80823f734a"), "a" : [ 2, 3, 4 ] }
{ "_id" : ObjectId("515272e2f1085f80823f734b"), "a" : [ 2, 3, 1 ] }
> db.array.count()
3
> db.array.count({"a":[1,2,3]})
1
> db.runCommand({"distinct":"array", "key":"a"})
{
    "values" : [
        1,
        2,
        3,
        4
    ],
    "stats" : {
        "n" : 3,
        "nscanned" : 3,
        "nscannedObjects" : 3,
        "timems" : 0,
        "cursor" : "BasicCursor"
    },
    "ok" : 1
}


分组:


> db.testgroup.find()
{ "_id" : ObjectId("5157937e12ebc6d285bdf6c1"), "ka" : 1, "kb" : 2 }
{ "_id" : ObjectId("5157938512ebc6d285bdf6c2"), "ka" : 1, "kb" : 1 }
{ "_id" : ObjectId("5157938912ebc6d285bdf6c3"), "ka" : 1, "kb" : 1 }
{ "_id" : ObjectId("5157938f12ebc6d285bdf6c4"), "ka" : 1, "kb" : 1 }
{ "_id" : ObjectId("5157939512ebc6d285bdf6c5"), "ka" : 1, "kb" : 1 }
> db.testgroup.group({
    "key":{"kb":1},
    "initial":{count:0},
    "reduce":function(currdoc, prevdoc){
        prevdoc.count+=currdoc.ka }
  })
[ { "kb" : 2, "count" : 1 }, { "kb" : 1, "count" : 4 } ]
>


initial文档在reduce执行时,会作为初始文档传递给后续过程作为累加器文档,最后返回这个initial文档。


reduce中系统会传递两个参数,当前文档和累加器文档。


GridFS:


GridFS用来存放大二进制文件


ashin@linux:~$ ls
disk  mongodb-note.txt  openshift  test  VirtualBox VMs  Wallpaper  workspace  公共的  模板  视频  图片  文档  下载  音乐  桌面
ashin@linux:~$ mongofiles put mongodb-note.txt
connected to: 127.0.0.1
added file: { _id: ObjectId('51579c73e0af6265ff63802d'), filename: "mongodb-note.txt", chunkSize: 262144, uploadDate: new Date(1364696179568), md5:"6cd61341da1784b37e692c862ef4be45", length: 30615 }
done!
ashin@linux:~$ rm mongodb-note.txt
ashin@linux:~$ ls
disk  openshift  test  VirtualBox VMs  Wallpaper  workspace  公共的  模板  视频  图片  文档  下载  音乐  桌面
ashin@linux:~$ mongofiles get mongodb-note.txt
connected to: 127.0.0.1
done write to: mongodb-note.txt
ashin@linux:~$ ls
disk  mongodb-note.txt  openshift  test  VirtualBox VMs  Wallpaper  workspace  公共的  模板  视频  图片  文档  下载  音乐  桌面
ashin@linux:~$



####主从复制


主从复制可用于备份、故障恢复、读扩展等。设置一个主节点,多个从节点,从节点就可以复制主节点的数据到本地。


在linux上的2612端口建一个主节点并设置为自动同步:`mongod --dbpath ./mongo/dbs/master/ --port 2612 --master --autoresync`


在windows上7474端口建个从节点:`mongod.exe --dbpath c:\data\db --port 7474 --slave --source 192.168.2.130:2612`


现在在主节点上添加数据,可以看到后台在打印同步信息,完成后到windows下去看,和主节点上的数据一样了。如果在从节点上添加数据的话,会提示not master。以从节点的身份运行mongo shell貌似不能连接上数据库,改成独立的mongod服务运行就好了。


####副本集


副本集是有自动故障恢复功能的主从集群,区别是副本集没有固定的主节点。


在192.168.2.130上创建数据库:`mongod --dbpath test/mongo/dbs/node2/ --port 10002 --replSet imsetname/192.168.2.108:10001`


在192.168.2.108上创建数据库:`mongod --dbpath test/mongo/dbs/node1/ --port 10001 --replSet imsetname/192.168.2.130:10002`


连接数据库初始化服务器:


   `mongo 192.168.2.130:10002/admin`


> db.runCommand({"replSetInitiate":{
... "_id":"imsetname",
... "members":[
...   {
...     "_id":1,
...     "host":"192.168.2.130:10002"
...   },
...   {
...     "_id":2,
...     "host":"192.168.2.108:10001"
...   }
... ]}})
{
"info" : "Config now saved locally.  Should come online in about a minute.",
"ok" : 1
}


进入数据库提示符变为:`imsetname:PRIMARY> `表示是master节点,可以进行操作,断开再次连接发现提示符变成:`imsetname:SECONDARY> `,再进行操作会提示错误信息。master节点是不确定的,它由其他节点选举出来。读扩展可以放在从节点上查询减轻主节点负载。


####分片


将数据库集合拆分,分散存在不同的机器上,mongodb可以自动进行分片。运行一个mongos路由进程,它知道所有数据存放的位置。


启动配置服务器:


ashin@linux:~/test/mongo$ mkdir dbs/config
ashin@linux:~/test/mongo$ mongod. --dbpath ./dbs/config --port 2612


建立mongos进程:


ashin@linux:~/test/mongo$ mongos --port 2712 --configdb localhost:2612


添加分片(普通的mongod实例或副本集):


ashin@linux:~/test/mongo$ mkdir dbs/shard1
ashin@linux:~/test/mongo$ mongod  --dbpath dbs/shard1 --port 7777
ashin@linux:~/test/mongo$ mkdir dbs/shard2
ashin@linux:~/test/mongo$ mongod  --dbpath dbs/shard2 --port 7778


连接mongos,为集群添加片:


ashin@linux:~/test/mongo$ mongo localhost:2712/admin
MongoDB shell version: 2.4.1
connecting to: localhost:2712/admin
mongos> db.runCommand({
... addshard:"localhost:7777",
... allowLocal:true //在localhost上运行片,生产环境中集群部署在不同的机器上
... })
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand({
... addshard:"localhost:7778",
... allowLocal:true
... })
{ "shardAdded" : "shard0001", "ok" : 1 }


切分数据:


mongos> db.runCommand({"enablesharding":"shardtest"}) //将shardtest数据库的分片功能打开
{ "ok" : 1 }
mongos> db.runCommand({"shardcollection":"shardtest.hehe", "key":{"_id":1}})    //对hehe集合按照_id来分片。
{ "collectionsharded" : "shardtest.hehe", "ok" : 1 }


管理分片:


mongos> use config  //切换到config数据库
switched to db config
mongos> db.shards.find()    //查询分片
{ "_id" : "shard0000", "host" : "localhost:7777" }
{ "_id" : "shard0001", "host" : "localhost:7778" }
mongos> db.databases.find() //查询已经在片上的数据库信息,partitioned表示是否启用分片功能,primary表示数据库最开始创建数据文件的位置
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0000" }
{ "_id" : "shardtest", "partitioned" : true, "primary" : "shard0000" }
mongos> db.chunks.find()    //块信息
{ "_id" : "shardtest.hehe-_id_MinKey", "lastmod" : { "t" : 1, "i" : 0 }, "lastmodEpoch" : ObjectId("51592a6afbb6a0314bd6a9c7"), "ns" : "shardtest.hehe", "min" : { "_id" : { "$minKey" : 1 } }, "max" : { "_id" : { "$maxKey" : 1 } }, "shard" : "shard0000" }
mongos> db.printShardingStatus()    //显示所有概要信息
--- Sharding Status ---
  sharding version: {
"_id" : 1,
"version" : 3,
"minCompatibleVersion" : 3,
"currentVersion" : 4,
"clusterId" : ObjectId("51592728fbb6a0314bd6a939")
}
  shards:
{  "_id" : "shard0000",  "host" : "localhost:7777" }
{  "_id" : "shard0001",  "host" : "localhost:7778" }
  databases:
{  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
{  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
{  "_id" : "shardtest",  "partitioned" : true,  "primary" : "shard0000" }
shardtest.hehe
shard key: { "_id" : 1 }
chunks:
shard00001
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0000 { "t" : 1, "i" : 0 }
mongos> use admin   //删除分片
switched to db admin
mongos> db.runCommand({"removeshard":"localhost:7777"})
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "shard0000",
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"shardtest",
"test"
],
"ok" : 1
}


先在mongos中插入数据后,在7777上可以查到,7778上没有数据,删除7777后,7778上有了数据。数据量太小的原因。


MongoDB有个0day,run操作可以直接执行shell命令。


文章为阿小信的个人笔记,转载请注明出处。