# 建立数据库文件夹,这个是默认存放数据的地方,但MongoDB不会自动建立 mkdir -p /data/db # 增长权限 chown -R $USER:$USER /data/db wget -qO - https://www.mongodb.org/static/pgp/server-4.0.asc | sudo apt-key add - # 导入公钥 echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list # 为MongoDB建立列表文件 sudo apt-get update # 从新加载本地数据包 sudo apt-get install -y mongodb-org=4.0.12 mongodb-org-server=4.0.12 mongodb-org-shell=4.0.12 mongodb-org-mongos=4.0.12 mongodb-org-tools=4.0.12 # 安装软件包 echo "mongodb-org hold" | sudo dpkg --set-selections echo "mongodb-org-server hold" | sudo dpkg --set-selections echo "mongodb-org-shell hold" | sudo dpkg --set-selections echo "mongodb-org-mongos hold" | sudo dpkg --set-selections echo "mongodb-org-tools hold" | sudo dpkg --set-selections # 保持目前的版本,防止自动更新 # 启动 sudo service mongodb start #或者 systemctl start mongodb
sudo apt-get purge mongodb-org* sudo rm -r /var/log/mongodb sudo rm -r /var/lib/mongodb
报错以下:javascript
Failed to start mongodb.service: Unit mongodb.service not found.java
解决:正则表达式
sudo nano /etc/systemd/system/mongdb.service # 建立服务文件
[Unit] Description=High-performance, schema-free document-oriented database After=network.target [Service] User=mongodb ExecStart=/usr/bin/mongod --quiet --config /etc/mongod.conf # 制定须要执行的命令的位置, # 制定项目运行所须要的配置文件位置 [Install] WantedBy=multi-user.target
在mongodb中数据是以文档的形式存在的mongodb
一、每一个文档至关于一条记录shell
二、多个文档组合在一块儿,就是集合,一个集合就至关于一张数据表数据库
三、多个集合组合在一块儿,就是数据库,每一个数据库就是一个文件夹json
增长:使用insert()函数,将要插入的数据放到集合中ubuntu
post = {"title": "my first mongo"}
db.blog.insert(post)
查找:使用find()或者findOne()数组
db.blog.find()
db.blog.findOne()
update()方法除了接收前两个参数外,还能够接收另外两个参数,而且这两个参数都是布尔值bash
例如:db.blog.update({"title": "My Blog Post"}, {"title": "My Blog Get"}, true, true)
第三个参数表示upsert,可以保证操做的原子性,同时在没有查询到制定的集合状况下,会以查询条件和更新文档为基础新建一个文档,第四个参数默认是true,表示更新全部符合条件的集合,若改成false,则只更新第一个。
给他增长一个属性:post.comments = []
db.blog.update({"title":"my first mongo"}, post)
删除:remove(),在不给出参数的状况下,删除集合中的全部文档,给出参数后,会删除对应的文档
> help
db.help() | help on db methods |
---|---|
db.mycoll.help() | help on collection methods |
sh.help() | sharding helpers |
rs.help() | replica set helpers |
help admin | administrative help |
help keys | key shortcuts |
help connect | connecting to a db help |
help misc | misc things to know |
help mr | mapreduce |
show dbs | show database names |
show collections | show collections in current database |
show users | show users in current database |
show profile | show most recent system.profile entries with time >= 1ms |
show logs | show the accessible logger names |
use <db_name> | set current database |
db.foo.find() | list objects in collection foo |
db.foo.find( { a : 1 } ) | list objects in foo where a == 1 |
it | result of the last line evaluated; use to further iterate |
DBQuery.shellBatchSize = x | set default number of items to display on shell |
exit | quit the mongo shell |
一、当集合名与内置的函数名相同时,是没有办法经过db.集合名来访问的
二、当集合名名包含-时,好比:six-four,一样没有办法经过正常的方法访问集合,引文shell对其的解释是两个变量的相减
最终的解决办法是经过__getCollection()__来访问,例如:db.getCollection("version"),db.getCollection("six-four")这样才能正常访问
save是一个shell函数,能够在文档不存在的时候插入,存在的时候更新,它只有一个参数,即文档自己
save会调用upsert,即实现文档的自动建立和更新
var x = db.foo.findOne()
x.num = 12
db.foo.save(x)
修改器 | 用法 | 做用 |
---|---|---|
$inc | db.x.update({"a":1}, {$inc: {"b":1}}) | 在原有b的基础上加1 |
$set | db.x.update({"a":1}, {$set: {"b":"a"}}) | 将原有b的数据修改成a,若b不存在,则建立一个 |
$unset | db.x.update({"a":1}, {$unset: {"b":1}}) | 撤销修改,此时的数值1,表示条件为真的意思 |
$push | db.x.update({"a":1}, {$push:{"comments": {"name":"json"}}}) | 该修改器只做用于数组,能够向文档中已有数组中添加值,固然数组不存在时,建立一个数组并添加对应内容 |
$pop | db.x.update({"a":1}, {$pop:{"comments": 1}}) db.x.update({"a":1}, {$pop:{"comments": -1}}) | 基于数组位置的删除,1表示从数组的尾部删除一个元素,-1表示从数组的头部删除一个元素 |
$addToSet | db.x.update({"a":1}, {$addToSet:{"email": "aa@163.com"}) | 该修改器只做用于数组,能够向数组中添加一个值,若数组中已经有了该值,则添加失败 |
$each | db.x.update({"a":1}, {$addToSet:{"email": {$each: ["1", "2", "3"]}}) | 能够遍历出数组中的每一个值,一般与$addToSet搭配使用,完成多个值得添加,若是存在不添加 |
$pull | db.x.update({"a":1}, {$pull:{"email": "1"}}) | 指定数组中的具体元素进行删除,若匹配到多个值,匹配多少删除多少 |
$数组定位符 | db.x.update({"comments.author": "jhon"}, {$set:{"comments.$.author": 'lili'}}) | 定位符只匹配第一个匹配到的文档 |
命令 | 用法 | 做用 |
---|---|---|
$gt | db.users.find({"age": {"$gt": 20}}) | 查询users集合中年龄大于20的文档 |
$gte | db.users.find({"age": {"$gte": 20}}) | 查询users集合中年龄大于等于20的文档 |
$lt | db.users.find({"age": {"$lt": 20}}) | 查询users集合中年龄小于20的文档 |
$lte | db.users.find({"age": {"$lte": 20}}) | 查询users集合中年龄小于等于20的文档 |
$ne | db.users.find({"username": {"$ne": "andy"}}) | 查询users集合中用户名不等于andy的文档 |
$or | db.users.find({"$or": [{"age": 20},{"username": "andy"} ]}) | $or 键对应的值是一个数组,知足数组中任何一个条件的文档都会被查找出来,可做用于不一样的键 |
$in | db.users.find({"age": {"$in": [12 ,10, 22]}}) | $in键对应的值是一个数组,知足数组中任何一个条件的文档都会被查找出来,可是它只做用于同一个键 |
$nin | db.users.find({"age": {"$nin": [12 ,10, 22]}}) | $nin键对应的值是一个数组,不知足数组中任何一个条件的文档都会被查找出来,它也只做用于同一个键 |
$mod | db.users.find({"age": {"$mod": [5, 1]}}) | $mod表示取模运算,运算完成后在做为查询条件,它对应的值是一个数组,该数组只有两个值且有顺序,第一个表示除数,第二个表示余数,在这里表达的意思是,找出年龄除以5后余数为1的文档 |
$not | db.users.find({"$not":{"age": {"$mod": [5, 1]}}}) | $not是元条件查询,即做用其余条件查询之上,例如他与$mod取模运算结合使用,表示取非 |
$existe | db.users.find({"x":{"$existe": true}}) | $existe判断该键是否真实存在,存在则显示出来 |
/joy/i | db.users.find({"username": /joy/i}) | 这里是利用正则表达式去匹配所查询文档的某个键对应的值,i表示不区分大小写 |
$where 自定义查询
db.stu.find({ $where:function() { return this.age>30;} // this 表明当前查询的文档,找出年龄大于30岁的文档 })
db.fruit.insert({"_id": 1, "fruits": ["banana", "peach", "apple"]})
db.fruit.insert({"_id": 2, "fruits": ["orange", "kumquat", "apple"]})
db.fruit.insert({"_id": 3, "fruits": ["banana", "cherry", "apple"]})
使用db.fruit.find({"fruits": {"$all" : ["banana", "apple"]}}),执行结果是数值fruits中只要包含有"banana"和"apple"元素的文档,所有返回,忽略数组中元素的顺序
{"fruits": {"$all" : ["banana"]}}和{"fruits":"banana"},这两条查询效果是同样的
好比:db.fruit.find({"fruits.2":"apple"}),只要数组中指定位置的元素匹配正确,就会返回结果
查询固定数组长度的文档
在文档中建立一个size的字段来专门描述数组的长度,变相的经过size的值来范围查找
db.fruit.update({"_id": 1}, {"$push" : {"fruits": "pear"}, "$inc" : {"size": 1}})
db.fruit.find({"size": {"$gt": 3}})
对查找到的数组进行切片处理,并返回新的切片后的文档
db.fruit.find({"_id" : 1}, {"fruits": 1}) >{ "_id" : 1, "fruits" : [ "banana", "peach", "apple", "pear"]} # 这里_id默认返回 # 若是将_id的值变为0,则不会被返回 db.fruit.find({"_id" : 1}, {"fruits": 1, "_id": 0}) # 数字表明真假 >{"fruits" : [ "banana", "peach", "apple", "pear"]} # 当对返回的键使用切片后$slice,文档中全部的键默认都会返回 db.fruit.find({"_id": 1}, {"fruit": {"$slice": 3}}) >{ "_id" : 1, "fruits" : [ "banana", "peach", "apple" ], "size" : 4 }
db.fruit.find({"_id": 1}, {"fruit": {"$slice": 3}}), $slcie对应的值是正数便可,获得数组的前三个元素
db.fruit.find({"_id": 1}, {"fruit": {"$slice": -3}}), $slcie对应的值是负数便可,获得数组的后三个元素
db.fruit.find({"_id": 1}, {"fruit": {"$slice": [1, 3]}}),$slice对应的值为数组,该数组表示你要操做的数组下标
,获得结果:{ "_id" : 1, "fruits" : [ "peach", "apple", "pear" ], "size" : 4 },包含起始和结束下标
{"name": {"first": "Joe", "last": "Schmoe"}, "age": 27},在集合people中
db.people.find({"name": {"first": "Joe", "last": "Schmoe"}}),这里能够找到有这个内嵌文档的文档,可是有一个缺点,就是查询条件必须匹配整个内嵌文档,不然就会匹配失败,同时顺序也不可以错,也就是要求精确匹配
db.people.find({"name.first": "Joe", "name.last": "Schmoe"}),这里就要求精确匹配了
将限定条件进行分组,仅当须要对一个内嵌文档的多个键操做时才会用到
db.blog.find({"comments": {"$elemMatch": {"author": "joe", "score": {"$gte": 5}}}})
db.collection.find().sort({"username":1, "age": -1})
先以username升序排列,若username相同,则按照age降序排列
db.collection.find().limit(20),表示每页返回20条数据
组合实现分页查询
按照年龄从大到小取出前二十条文档
跳过前20条,取后20条的结果
使用find函数返回的对象能够赋值给一个变量,这个变量就能够理解为是一个游标对象
游标对象属性 :可迭代(iterable)
游标对象方法 :hasNext()判断是否还有下一条数据
next()获取下一条数据
db.stu.count() # 返回fruit集合中的总文档数
现有以下集合mycol:
{ "_id" : 1, "name" : "tom", "sex" : "男", "score" : 100, "age" : 34 } { "_id" : 2, "name" : "jeke", "sex" : "男", "score" : 90, "age" : 24 } { "_id" : 3, "name" : "kite", "sex" : "女", "score" : 40, "age" : 36 } { "_id" : 4, "name" : "herry", "sex" : "男", "score" : 90, "age" : 56 } { "_id" : 5, "name" : "marry", "sex" : "女", "score" : 70, "age" : 18 } { "_id" : 6, "name" : "john", "sex" : "男", "score" : 100, "age" : 31 }
db.stu.aggregate({$group:{_id: "$sex", Count: {"$sum": 1}}})
db.stu.aggregate( {$group: { _id:"$gender", name:{$push:"$name"} } } ) 把全部的数据放到一块儿 $$ROOT, 把整个文档放到一个数组中 db.stu.aggregate( {$group: { _id:null, name:{$push:"$$ROOT"} } } )
db.stu.aggregate( {$match:{age:{$gt:20}} )
db.stu.aggregate( {$project:{_id:0,name:1,age:1}} ) //控制显示的文档键
db.stu.aggregate( {$group:{_id:"$gender",counter:{$sum:1}}}, {$sort:{counter:-1}} )
db.stu.aggregate( {$group:{_id:"$gender",counter:{$sum:1}}}, {$sort:{counter:-1}}, {$skip:1}, {$limit:1} )
db.runCommand({"distinct": "fruit" , "key": "fruits"})
runCommand指令表示运行命令,括号内的参数的第一个键为具体的指令,指令所对应的的值是要操做的集合,key对应的是要操做的键。
distinct所表达的意思是找出集合中某个键对应多少不一样的值,也就是去重。
db.stock.insert({"day" : "2010/10/03", "time": "10/03/2010 03:57:01 GMT-400", "price": "4.23"})
db.stock.insert({"day" : "2010/10/04", "time": "10/04/2010 11:28:39 GMT-400", "price": "4.27"})
db.stock.insert({"day" : "2010/10/03", "time": "10/03/2010 05:00:22 GMT-400", "price": "4.10"})
db.stock.insert({"day" : "2010/10/06", "time": "10/06/2010 05:27:58 GMT-400", "price": "4.30"})
db.stock.insert({"day" : "2010/10/04", "time": "10/04/2010 08:34:50 GMT-400", "price": "4.01"})
获取到天天最新的股票交易价格
db.runCommand({"group":{ "ns": "stock", "key": {"day": true}, // 程序执行到这里以后,就已经对集合分组完毕了 "$keyf": function(X){ return X.toLowerCase() // 将须要排序的键进行转换,好比进行大小写转换 }, "initial":{"time":0}, // 每组文档遍历时候的初始值 "$reduce":function(doc, prev){ if(doc.time>prev.time){ // 判断时间大小,更新要显示的最近时间 prev.time = doc.time; prev.price= doc.price; } }, "condition": {"day": {"$gt": "2010/10/03"}},// 对分组进行条件限制,必须大于条件时间 "finalize":function(prev){ //对返回结果作最后的修改,和限定 ... } }})
参数解析
group:对集合执行的操做,即分组
ns:须要操做的数据集
key:以文档中的哪一个键进行分组
$keyf: 对须要分组的键进行条件转换
initial: 每组文档的初始化值,也就是最终分完组后显示的字段的初始化值
$reduce: 对分组后的显示文档作最后的操做,在上述案例中,就是找到那一组文档中时间最新的文档,而后把他的时间和股票交易价格显示到咱们能够看到的结果
condition: 对分组进行条件限制
finalize: 对返回的结果作最后的修改
#### 13.三、findAndModify
db.runCommand({"findAndModify": "stock", # 操做集合stock
"query": {"day":{"$gt": "2010/09/30"}}, # 查询条件
"sort": {"day": -1}, # 排序键
"remove": true # 是否删除文档true
})
#### 13.四、建立固定大小的集合
db.creatCollection("my_collection",{"capped": true, "size": 100000})
参数解析
my_collection:集合名
capped:表示是否限值集合的大小,true表示限值,false表示不限制
size:表示集合大小,这里表示100000个字节
更多技术资讯可关注:gzitcast