深入浅出MongoDB(二)
文章目录
添加文档
文档的数据结构BSON是一种类似json的二进制形式的存储格式,称为二进制json(Binary JSON)。
- 使用insert方法添加文档,虽然insert方法被标记为废弃,还是可以使用
shell
> db.test_dev.insert({title: 'turtle', description: '今天是个好日子'})
# 查看已插入的文档
> db.test_dev.find()
[
{
"_id": {"$oid": "66f609a0ea7bbd7d46df40d9"},
"description": "今天是个好日子",
"title": "turtle"
}
]
- 使用insertOne可以添加一个文档,如果使用insertOne添加多个文档,也只有第一个文档会被添加
shell
> db.test_dev.insertOne({'id': '001', 'name': '张三', 'age': 10})
[
{
"_id": {"$oid": "66f3d2a2aab45b2857fdc9a0"},
"age": 10,
"id": "001",
"name": "张三"
}
]
> db.test_dev.insertOne({'id': '002', 'name': '李四', 'age': 10}
> db.test_dev.insertOne({'id': '003', 'name2': '张三', 'age': 10}, {'id': '004', 'name2': '张三', 'age': 10})
- 使用insertMany添加多个文档
shell
> db.test_dev.insertMany([{'id': '003', 'name': '王五', 'age': 12}, {'id': '004', 'name': '赵六', 'age': 14}])
[
{
"_id": {"$oid": "66f60cc5ea7bbd7d46df40e2"},
"age": 12,
"id": "003",
"name": "王五"
},
{
"_id": {"$oid": "66f60cc5ea7bbd7d46df40e3"},
"age": 14,
"id": "004",
"name": "赵六"
}
]
更新文档
- 使用update方法更新集合中的文档
shell
# query是update的查询条件
# update是更新的对象和一些更新的操作符
# upsert可选参数,如果不存在更新的记录是否插入新对象,默认不插入
# multi可选参数,默认false,只更新找到的第一条记录,如果为true,则更新多条记录
# writeConcern:可选参数,抛出异常的级别
db.collection.update(<query>, <update>, {upsert:<boolean>, multi:<boolean>, writeConcern:<document>})
- 使用update方法更新文档
shell
> db.test_dev.updateOne({'id': '002'}, {'$set':{'age':'13'}})
[
{
"_id": {"$oid": "66f3d2ccaab45b2857fdc9a2"},
"age": "13",
"id": "002",
"name": "李四"
}
]
删除文档
- 使用deleteOne方法移除一个文档
shell
> db.test_dev.deleteOne({_id: new ObjectId('66f60b84ea7bbd7d46df40df')})
[
{
"acknowledged": true,
"deletedCount": 1
}
]
- 使用findOneAndDelete方法移除一个文档并返回
shell
> db.test_dev.findOneAndDelete({_id: new ObjectId('66f609a0ea7bbd7d46df40d9')})
[
{
"_id": {"$oid": "66f609a0ea7bbd7d46df40d9"},
"description": "今天是个好日子",
"title": "turtle"
}
]
- 使用deleteMany方法移除多个文档
shell
> db.test_dev.deleteMany({_id: {$in: [new ObjectId('66f60b2fea7bbd7d46df40db'), new ObjectId('66f60cc5ea7bbd7d46df40e3')]}})
[
{
"acknowledged": true,
"deletedCount": 2
}
]
> db.test_dev.deleteMany({_id: {$in: [ObjectId('66f3d2ccaab45b2857fdc9a2')]}})
查询文档
- 使用find方法查看文档
shell
> db.test_dev.find()
[
{
"_id": {"$oid": "66f3d2a2aab45b2857fdc9a0"},
"age": 10,
"id": "001",
"name": "张三"
},
{
"_id": {"$oid": "66f60cc5ea7bbd7d46df40e2"},
"age": 12,
"id": "003",
"name": "王五"
}
]
- mongodb查询条件操作
shell
# 等于
> db.test_dev.find({db.test_dev.find({_id: ObjectId('66f3d2a2aab45b2857fdc9a0')})})
# 小于$lt,小于等于$lte, 大于$gt,大于等于$gte,不等于$ne
> db.test_dev.find({likes:{$lt:50}})
# AND条件,传入多个以逗号分隔的键
> db.test_dev.find({name:'张三', age:12})
# OR条件,使用关键字$or
> db.test_dev.find({$or:[{name:'张三'}, {age:12}]})
条件操作符
$type
操作符是基于BSON类型来检索集合中匹配的数据类型并返回结果
shell
1 - Double,2 - String, 3 - Object, 4 - Array, 5 - Binary data, 6 - Undefined, 7 - Object id, 8 - Boolean, 9 - Date, 10 - Null, 11 - Regular Expression, 13 - JavaScript, 14 - Symbol, 15 - JavaScript(with scope), 16 - 32bit integer, 17 - Timestamp, 18 - 64bit integer, 255 - Min key, 127 - Max key
- 获取test_dev集合中name为String的数据
shell
db.test_dev.find({"name": {$type:2}})
[
{
"_id": {"$oid": "66f3d2a2aab45b2857fdc9a0"},
"age": 10,
"id": "001",
"name": "张三"
},
{
"_id": {"$oid": "66f60cc5ea7bbd7d46df40e2"},
"age": 12,
"id": "003",
"name": "王五"
}
]
limit与skip
- limit方法可以读取指定数量的文档,接收一个数字参数
shell
> db.test_dev.find().limit(1)
[
{
"_id": {"$oid": "66f3d2a2aab45b2857fdc9a0"},
"age": 10,
"id": "001",
"name": "张三"
}
]
- skip方法可以用来跳过指定数量的数据,接收一个数字参数
shell
# 跳过第一个文档,显示第二个文档
> db.test_dev.find().limit(1).skip(1)
[
{
"_id": {"$oid": "66f60cc5ea7bbd7d46df40e2"},
"age": 12,
"id": "003",
"name": "王五"
}
]
排序
- sort方法用来对数据排序,可以通过参数指定排序的字段,并通过1和-1指定排序的方式,1为升序排列,而-1用于降序排列。
shell
# 按年龄降序排列
> db.test_dev.find().sort({age:-1})
[
{
"_id": {"$oid": "66f646c4ea7bbd7d46df40e6"},
"age": 18,
"id": "002",
"name": "李四"
},
{
"_id": {"$oid": "66f60cc5ea7bbd7d46df40e2"},
"age": 12,
"id": "003",
"name": "王五"
},
{
"_id": {"$oid": "66f3d2a2aab45b2857fdc9a0"},
"age": 10,
"id": "001",
"name": "张三"
}
]
索引
- 使用ensureIndex方法创建索引
shell
# 给name字段创建索引,1为升序,-1为降序
> db.test_dev.ensureIndex({name:1})
name_1
# 给多个字段创建索引
> db.test_dev.ensureIndex({name:1, age:-1})
- ensureIndex函数的可选参数
参数名 | 类型 | 说明 |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,默认值为false |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false |
name | string | 索引的名称。如果未指定,通过连接索引的字段名和排序顺序生成一个索引名称 |
dropDups | Boolean | 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false |
sparse | Boolean | 对文档中不存在的字段数据不启用索引;如果设置为true,在索引字段中不会查询出不包含对应字段的文档。默认值为 false |
expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 |
v | index version | 索引的版本号,默认的索引版本取决于创建索引时运行的版本 |
weights | document | 索引权重值,数值在1到 99999 之间,表示该索引相对于其他索引字段的得分权重 |
default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表,默认为英语 |
language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
- 查看集合中创建的索引
shell
> db.test_dev.getIndexes()
[
{
"key": {
"_id": 1
},
"name": "_id_",
"ns": "tax_engine.test_dev",
"v": 2
},
{
"key": {
"name": 1
},
"name": "name_1",
"ns": "tax_engine.test_dev",
"v": 2
},
{
"key": {
"name": -1
},
"name": "name_-1",
"ns": "tax_engine.test_dev",
"v": 2
}
]
- 使用createIndex方法创建索引
shell
> db.test_dev.createIndex({age:1})
[
{
"key": {
"age": 1
},
"name": "age_1",
"ns": "tax_engine.test_dev",
"v": 2
}
]
- 使用dropIndex方法删除索引,dropIndexes方法删除多个索引
shell
# 删除索引age_1
> db.test_dev.dropIndex("age_1")
[
{
"nIndexesWas": 4,
"ok": 1
}
]
> db.test_dev.dropIndexes(["<index1>", "<index2>"])
# 删除除了_id索引外的所有索引
> db.test_dev.dropIndexes()
聚合
- 聚合主要用来处理数据并返回计算后的数据结果
shell
# 相当于select id, count(*) from test_dev group by id
> db.test_dev.aggregate([{$group: {_id:"$id", total:{$sum:1}}}])
[
{
"_id": "003",
"total": 1
},
{
"_id": "002",
"total": 1
},
{
"_id": "001",
"total": 1
}
]
- 聚合表达式
shell
# $sum计算总和,$avg计算平均值,$min获取集合所有文档对应值的最小值,
# $max获取集合中所有文档对应值的最大值
> db.test_dev.aggregate([{$group:{_id:'$id', total:{$sum:'$age'}}}])
# $push在结果文档中插入值到一个数组中
> db.test_dev.aggregate([{$group:{_id:'$id', total:{$push:'$age'}}}])
[
{
"_id": "003",
"total": [12]
},
{
"_id": "002",
"total": [18, 21]
},
{
"_id": "001",
"total": [10]
}
]
# $addToSet在结果文档中插入值到一个数组中,但不创建副本
> db.test_dev.aggregate([{$group:{_id:'$id', total:{$addToSet:'$age'}}}])
# $first根据资源文档的排序获取分组后第一个文档数据
> db.test_dev.aggregate([{$group:{_id:'$id', total:{$first:'$age'}}}])
# $last根据资源文档的排序获取分组后最后一个文档数据
> db.test_dev.aggregate([{$group:{_id:'$id', total:{$last:'$age'}}}])
- 管道在linux中一般用来把当前命令的输出结果作为下一个命令的参数。mongodb的聚合管道把文档在一个管道处理完毕后的结果传递给下一个管道处理,管道操作可以试重复的。
shell
$project:修改输入文档的结构,可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档
$match:用来过滤数据,只输出符合条件的文档
$limit:限制聚合管道返回的文档数
$skip:在聚合管道中跳过指定数量的文档,返回余下的文档
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
$group:将集合中文档分组,可用于统计结果
$sort:将输入文档排序后输出
$geoNear:输出接近某一地理位置的有序文档
# _id:0不加上结果会有_id字段
> db.test_dev.aggregate({$project: {_id:0, name:1, age:1}})
# 用户分数大于70小于等于90的记录,然后把符合条件的记录送到$group管道处理
> db.test_dev.aggregate([
{$match: {socre:{$gt:70, $lte:90}}},
{$group: {_id:nll, count:{$sum:1}}}
])