MongoDB笔记

2019/09/30 MongoDB

概述

  • 非关系型数据库
    • 键值数据库:redis、flare:极高的读写性能,用于处理大量数据的高访问负载,主要用作缓存
    • 文档型数据库:MongoDB:满足海量数据存储,对字段要求不严格,不需要预先定义表结构,并发写入速度高
    • 列存储数据库:Hbase:查找速度快,可拓展性强
    • 图数据库:InfoGrid、Neo4J:适用于关系图谱

MongoDB快速入门

  • 概念:集合Collection-文档Document-字段Field
  • _id:Object Id,由时间、机器码、进程pid和自增计数构成,始终递增绝不重复;前八位字符转换为十进制就是时间戳

插入

db.getCollection('xx').insertOne({"name":"xx","age":17})

db.getCollection('xx').insertMany([
{"name":"xx","age":17},
{"name":"xx","age":18}
])

查询

db.getCollection('xx').find()
db.getCollection('xx').find({'字段1':'值1','字段2':'值2'})
db.getCollection('xx').find({'age':{'$get':25,'$lte':28})

// 限定返回,只可能全1或全1
db.getCollection('xx').find({'age':{'$get':25,'$lte':28}, {'name':1,'age':1})

// 排序 1正序 -1倒序
db.getCollection('xx').find({'age':{'$get':25,'$lte':28}).sort({'字段名':-1})

修改

db.getCollection('xx').updateOne({'name':'x'}, {'$set':{'address':'xx'}})
db.getCollection('xx').updateMany({'name':'x'}, {'$set':{'address':'xx'}})

### 删除

// 返回的数据中,acknowledged为true表示删除成功,deletedCount表示删除的条数
db.getCollection('xx').deleteOne({'name':'x'})
db.getCollection('xx').deleteMany({'name':'x'})

数据去重

db.getCollection('xx').distinct('age')
db.getCollection('xx').distinct('age',{'age':{'$gte':13}})

MongoDB高级语法

### AND\OR

db.getCollection('xx').find('$and':[{'age':{'$gte':3}}, {'sex':'男'}])
db.getCollection('xx').find('$or':[{'age':{'$gte':3}}, {'sex':'男'}])
db.getCollection('xx').find('$and':[
'$or':[{'age':{'$gte':3}}, {'sex':'男'}], 
'$or':[{'age':{'$gte':3}}, {'sex':'男'}]
])

数组中查询

  • 查询数组中包含和不包含,和普通的字段查询相同
// 查询数组长度:$size
db.getCollection('xx').find({'price':{'$size':2})
// 查询数组中第1个数据
db.getCollection('xx').find({'size.0':'S')
db.getCollection('xx').find({'price.0':'$get':500)

聚合查询

  • db.getCollection(‘xx’).aggregate([阶段1,阶段2,阶段3,…])
  • $match:筛选,$project:字段相关,$group:分组相关 #### $match
db.getCollection("sensor_property_records").aggregate([
	{
        $match: {
        	"device_sn" : {
        	    "$in" : [
        	        "2CF7F15000100102", 
        	        "2CF7F15000100105"
        	    ]
        	}, 
        	"ctime" : {
        	    "$gte" : 1564452038000.0, 
        	    "$lte" : 1565056838000.0
        	}
       }
	},
	{
    	$sort: {ctime:-1}, 
    },
    {
    	$limit:100
    }
]);

#### $project - $project,如果一个字段不是0或1,而是字符串,则直接输出该字符串;如果是$+已有字段名,则复制该字段的值

// 返回特定字段,并增加一个新字段
db.getCollection('xx').aggregate([{'$match':{'age':{'$get':25,'$lte':28}}},{'$project':{'sex':1,'age':1, 'hello':'word'}}])

db.getCollection('xx').aggregate([{'$match':{'age':{'$get':25,'$lte':28}}},{'$project':{'sex':1,'age':1, 'hello':'$age'}}])

db.getCollection('xx').aggregate([{'$match':{'age':{'$get':25,'$lte':28}}},{'$project':{'sex':1,'age':'this is age'}])
  • 用于抽取嵌套字段
db.getCollection('xx').aggregate([$project])
  • $literal用于显示特殊字符
db.getCollection('xx').aggregate([{'$project':{'hello':{'$literal':'$normalstring'}}}])

#### $group - $sum,$avg,$max,$min - 去重

// 返回记录
db.getCollection('xx').aggregate([{'$group':{'_id':'$name'}}])

db.getCollection('xx').aggregate([{'$group':{'_id':'$name',
'max_score':{'$max':'$字段名'},
'sum_score':{'$sum':'$字段名'},
}}])

  • $sum可以使用数字1,返回统计条数
  • $last:取最后一条数据,$first:取最新的一条数据
db.getCollection('xx').aggregate([{'$group':{'_id':'$name',
'date':{'$last':'$date'},
'score':{'$last':'$score'},
}}])

### $unwind - 拆分数组,将包含数组的记录拆分为多条记录,每条中拥有数组的一个元素

db.getCollection('xx').aggregate([{'$unwind':'$size}])

### 联集查询

db.getCollection('xx').aggregate([
{
  '$lookup':{
    'from':'被查集合名',
    'localField':'主集合字段',
    'foreignField':'被查集合字段',
    'as':'保存查询结果的字段名' // 嵌入式文档
    }  
}])

安全及性能

  • 批量插入
  • 索引,空间换时间
  • 以插入数据代替更新
  • 冗余信息
  • 字符串比较数字,左侧补0
  • admin数据库是MongoDB自带的数据库

Search

    Table of Contents