前言
这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
文档CURD
文档的数据结构和JSON基本一样,存储在集合中的数据都是**BSON(Binary JSON)**格式,为二进制JSON
插入文档
db.connection_name.insert(document)
、db.connection_name.save(document)
> db.test_coll.save({"test":1})
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : "61303f6c27b08b32c2c72c05"
})
save方法在出现重复_id主键
时会更新,不重复则创建
该方法新版本中已废弃,可以使用db.collection.insertOne()
或db.collection.replaceOne()
来代替
db.collection.insertOne(document)
、db.collection.insertMany(document)
> db.test_coll.insertOne({"1":1})
{
"acknowledged" : true,
"insertedId" : ObjectId("6130470b4febbde5afbf754c")
}
> db.test_coll.insertMany([{"1":1},{2:2}],{ordered:false})
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("6130472e4febbde5afbf754f"),
ObjectId("6130472e4febbde5afbf7550")
]
}
ordered
控制按照顺序写入,默认为true
查找文档
查找文档使用: db.collection.find
比如查找所有名字为王欣欣的数据
db.test_coll.find({name:"abc"})
过滤操作符
- 比较
- | 描述 |
---|---|
$eq | 匹配等于指定值的值。 |
$gt | 匹配大于指定值的值。 |
$gte | 匹配大于或等于指定值的值。 |
$in | 匹配数组中指定的任何值。 |
$lt | 匹配小于指定值的值。 |
$lte | 匹配小于或等于指定值的值。 |
$ne | 匹配所有不等于指定值的值。 |
$nin | 不匹配数组中指定的任何值。 |
- 逻辑
- | 描述 |
---|---|
$and | 使用逻辑连接查询子句AND 返回与两个子句的条件匹配的所有文档。 |
$not | 反转查询表达式的效果并返回与查询表达式不匹配的文档。 |
$nor | 将查询子句与逻辑连接NOR 返回所有未能匹配两个子句的文档。 |
$or | 使用逻辑连接查询子句OR 返回与任一子句的条件匹配的所有文档 |
- 检查
- | 描述 |
---|---|
$exists | 匹配具有指定字段的文档。 |
$type | 如果字段为指定类型,则选择文档。 |
- 表达式
- | 描述 |
---|---|
$expr | 允许在查询语言中使用聚合表达式。 |
$jsonSchema | 根据给定的 JSON 模式验证文档。 |
$mod | 对字段的值执行模运算并选择具有指定结果的文档。 |
$regex | 选择值与指定正则表达式匹配的文档。 |
$text | 执行文本搜索。 |
$where | 匹配满足 JavaScript 表达式的文档。 |
- 数组
- | 描述 |
---|---|
$all | 匹配包含查询中指定的所有元素的数组。 |
$elemMatch | 如果数组字段中的元素匹配所有指定$elemMatch 条件,则选择文档。 |
$size | 如果数组字段是指定大小,则选择文档。 |
查找示范
插入一些测试数据
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
- 查询数组结果
db.inventory.find( { tags: ["red", "blank"] } )
- 查询数组结果,不论顺序,只要包含这俩就可以
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
- 查询包含某个tags
db.inventory.find( { tags: "red" } )
- 查询数组
dim_cm
中至少包含一个值大于25
的所有文档
db.inventory.find( { dim_cm: { $gt: 25 } } )
- 一个元素可以满足大于
15
条件,另一个元素可以满足小于20
条件,或者单个元素可以同时满足两者
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
- 如果希望数组对象满足全部的条件,可以使用
elemMatch
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )
使用点表示法,您可以为文档中特定索引或数组位置的字段指定查询条件。该数组使用从零开始的索引
使用点表示法查询时,字段和索引必须在引号内。
db.inventory.find( { 'dim_cm.0': { $lte: 20 } } )
- 返回指定字段
可以在查询条件的第二个大括号处,通过{field: 0/1}
来标记是否返回当前字段
比如_id
在结果中
db.inventory.find( {}, { _id:0 } )
- 返回
instock
数组中的最后一个结果
$slice
传两个参数代表切片
db.inventory.find( { }, { instock: { $slice: -1 } } )
注意: mongo对于数组的匹配是默认符合其一即可
- 空值查询
查询匹配包含item
其值为null
或不包含该item
字段的字段的文档
db.inventory.find( { item: null } )
如果希望查询到的结果含有item字段,只是值为null,使用$type手动指明类型
db.inventory.find( { item : { $type: 10 } } )
- 存在检查
通过$exists
可以检查是否存在该字段的数据们,比如查找不存在item的数据行
db.inventory.find( { item : { $exists: false } } )
- 正则查询
通过$regex
可以完成对文本内容的正则匹配
db.inventory.find( { item : { $regex: /^p/ } } )
Sort
对数据结果进行排序
db.collection_name.find().sort({KEY:1})
价值 | 描述 |
---|---|
1 | 升序。 |
-1 | 降序排列。 |
Skip
跳过指定数量的数据
db.collection_name.find().skip(5)
Limit
读取指定数量的数据记录
db.collection_name.find().limit(10)
Count
查询全表的记录条数
db.collection_name.find().count()
如果在结合一些skip
、limit
时,只想获取到拿到的数据条数,可以结合count
参数true/1
db.collection_name.find().skip(10).limit(5).count(1);
例子
总是先sort
再skip
,最后limit
db.test.insertMany([
{_id:3, "name":"abc姑娘","age":16},
{_id:5, "name":"abc壮年","age":33},
{_id:2, "name":"abc青年","age":25},
{_id:1, "name":"abc老年","age":80},
{_id:6, "name":"abc婴儿","age":1},
{_id:10, "name":"abc青年+","age":27},
{_id:12, "name":"abc壮年+","age":35},
{_id:7, "name":"abc更年","age":45},
{_id:4, "name":"abc更年+","age":50},
])
db.test.find({"_id": {"$gt": 0, "$lt": 13}}).skip(6).sort({"_id":-1})
更新文档
db.update(<filter>, <update>, <options>)
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>, // Added in MongoDB 4.2
let: <document> // Added in MongoDB 5.0
}
)
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
- collation: 可选的,指定操作要使用的排序规则,常用于字符串结果排序
3.2版中的新功能
db.collection.updateOne()
: 即使多个文档可能与指定的过滤器匹配,也最多更新与指定过滤器匹配的单个文档
db.collection.updateMany()
: 更新与指定过滤器匹配的所有文档,查找与过滤器匹配的第一个文档并应用指定的更新修改
db.collection.replaceOne()
: 即使多个文档可能与指定的过滤器匹配,也最多替换与指定过滤器匹配的单个文档
db.collection.updateOne(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2.1
}
)
以下方法也可以更新集合中的文档
db.collection.findOneAndReplace()
db.collection.findOneAndUpdate()
字段更新操作符
- | 描述 |
---|---|
$currentDate | 将字段的值设置为当前日期,作为日期或时间戳,字段不存在则创建 |
$inc | 将字段的值增加指定的数量 |
$min | 仅当指定值小于现有字段值时才更新该字段 |
$max | 仅当指定值大于现有字段值时才更新该字段 |
$mul | 将字段的值乘以指定的数量 |
$rename | 重命名字段 |
$set | 设置文档中字段的值 |
$setOnInsert | 如果更新导致插入文档,则设置字段的值。对修改现有文档的更新操作没有影响 |
$unset | 从文档中删除指定的字段 |
数组更新操作符
- | 描述 |
---|---|
$ | 充当占位符以更新与查询条件匹配的第一个元素。 |
$[\] | 充当占位符,为匹配查询条件的文档更新数组中的所有元素。 |
$[\] | 充当占位符,arrayFilters 为符合查询条件的文档更新符合条件的所有元素。 |
$addToSet | 仅当集合中尚不存在元素时,才将元素添加到数组中。 |
$pop | 删除数组的第一项或最后一项。 |
$pull | 删除与指定查询匹配的所有数组元素。 |
$push | 将项目添加到数组。 |
$pullAll | 从数组中删除所有匹配的值。 |
- | 描述 |
---|---|
$each | 修改$push 和$addToSet 运算符以附加多个项目以进行数组更新。将一个数组内数据作为单独元素依次加入 |
$position | 修改$push 运算符以指定要在数组中添加元素的位置。 |
$slice | 修改$push 运算符以限制更新数组的大小。 |
$sort | 修改$push 运算符以重新排序存储在数组中的文档。 |
示范
db.test.insertMany([
{_id:3, "name":"abc姑娘","age":16},
{_id:5, "name":"abc壮年","age":33},
{_id:2, "name":"abc青年","age":25},
{_id:1, "name":"abc老年","age":80},
{_id:6, "name":"abc婴儿","age":1},
{_id:10, "name":"abc青年+","age":27},
{_id:12, "name":"abc壮年+","age":35},
{_id:7, "name":"abc更年","age":45},
{_id:4, "name":"abc更年+","age":50},
])
- 为所有王欣欣青年开头的数据的年纪+1
db.test.updateMany({name:{$regex: /^abc青年/}},{$inc:{age:1}})
- 为第一个王欣欣的num数组中,添加一个新的值,这只会影响目前具有
num
字段的数据
$addToSet
只有当这个值在数组中不存在时才增加
db.test.update({name:"abc姑娘"},{$addToSet: {num: {1:1}}})
- 更新num数组包含数字为2的,将这个2更新为-1
由于并不确定具体更新的数组位置,那么可以用$
来暂时站位代替
db.test.updateMany({num:2},{$set:{"num.$":-1}})
更新参考
- 插入一些数据
db.test_coll.insertMany([
{name:'abc'},
{name:'王AB'},
{name:'abc '},
])
- 更新所有王姓为李姓
db.update
删除文档
db.collection.deleteMany(
<filter>,
{
writeConcern: <document>,
collation: <document>
}
)
db.collection.deleteOne(
<filter>,
{
writeConcern: <document>,
collation: <document>,
hint: <document|string> // Available starting in MongoDB 4.4
}
)
删除操作不会删除索引,即使从集合中删除所有文档也是如此
批量操作
MongoDB 为客户端提供了批量执行写入操作的能力
批量写入操作影响单个集合,MongoDB 允许应用程序确定批量写入操作所需的可接受确认级别
db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
}
)
operations
[array]: bulkWrite
操作的数组。支持操作: insertOne
、updateOne
、updateMany
、deleteOne
、deleteMany
、replaceOne
writeConcern
[document]: 可选,写入确认有关参数
ordered
[boolean]: 可选,表示mongod实例有序还是无序执行操作。默认值true
-
使用有序的操作列表,MongoDB 以串行方式执行操作
- 如果在处理其中一个写入操作的过程中发生错误,MongoDB 将返回而不处理列表中的任何剩余写入操作
-
使用无序列表的操作,MongoDB 可以并行执行操作
- 但不能保证这种行为。如果在处理其中一个写操作的过程中发生错误,MongoDB 将继续处理列表中剩余的写操作
在分片集合上执行有序的操作列表通常比执行无序列表慢,因为对于有序列表,每个操作都必须等待前一个操作完成