暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MongoDB操作符

前端下饭师 2021-07-16
674

MongoDB介绍

MongoDB
 是由C++
语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB
 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB
 将数据存储为一个文档,数据结构由键值(key=>value
)对组成。MongoDB
 文档类似于 JSON
 对象。字段值可以包含其他文档,数组及文档数组。
如下这种结构

MongoDB命令行简单操作

假设存在数据库名称为database

并且存在一个集合为collection

集中collection
中有如下数据

[
{
"name": "Daniel",
"age": 24,
"job": "it",
"hobby": "travel"
},
{
"name": "Mike",
"age": 18,
"job": "student",
"hobby": "travel"
}
]

复制
  • 创建数据库或使用数据库
    use database

  • 删除数据库
    db.dropDatabase()

  • 查看数据库列表
    show dbs

  • 创建集合
    执行use
    操作后
    db.collection.opertion

    没有创建集合的语法,直接对指定集合进行操作就会创建该集合

  • 查看当前数据库的集合列表
    show collections

  • 删除集合
    db.collection.drop()

  • 查找

  1. 执行find
    命令
    db.collection.find({ hobby: "travel" })

    得到以下结果

find
命令会找到符合查询条件的所有结果
可以在后面跟上.pretty()
来让数据展示更美观。
后面跟.count()
返回查找到的数量
后面跟.sort()
返回排序后的数据
比如这样db.collection.find({ hobby: "travel" }).sort({ age: 1 })
1
表示升序,2
降序

  1. 执行findOne
    命令
    db.collection.findOne({ hobby: "travel" })


    findOne
    只会找到符合条件的第一条

  • 删除

  1. 执行deleteOne
    命令
    db.collection.deleteOne({ hobby: "travel" })

    得到以下结果

    deleteOne
    命令会删除符合查询条件的第一条数据

  2. 执行deleteMany
    命令
    db.collection.deleteMany({ hobby: "travel" })

    deleteMany
    命令会删除符合查询条件的所有数据

  • 插入

  1. 执行insertOne
    命令
    db.collection.insertOne({ "name": "Rick", "age": 32, "job": "teacher", "hobby": "sport" })

    insertOne
    命令可以添加一条数据到集合中
    他有一个可选参数{ writeConcern }
    ,写入策略,默认为 1,即要求确认写操作,0 是不要求。

  2. 执行insertMany
    命令

    db.collection.insertMany([
    {
    "name": "Jack",
    "age": 12,
    "job": "student",
    "hobby": "watch tv"
    },
    {
    "name": "Mary",
    "age": 8,
    "job": "student",
    "hobby": "book"
    }
    ])

    复制

    insertMany
    允许同时插入多条数据到集合中
    他有一个可选参数{ writeConcern, ordered }
    ,writeConcern意义同上,orderd表示是否按顺序写入,默认 true,按顺序写入。

  • 更新

  1. 执行updateOne
    命令
    db.collection.updateOne({ "name": "Mike" }, { $set: { "age": 20 } })

    updateOne
    命令可以更新匹配条件的第一条数据

  2. 执行updateMany
    命令
    db.collection.updateMany({ "hobby": "travel" }, { "hobby": "watch tv" })

    updateMany
    命令可以更新匹配条件的所有数据

还有几个可选参数,可自行百度

MongoDB操作符

接下来介绍的是MongoDB
中一些常用的操作符,暂时将操作符分为更新和查找两类。

查找操作符

下面介绍的,是常用的查询操作符🌰

  1. $all
    查找字段中包含指定内容的值,且需要包含全部指定的值,针对数组型字段

    db.collection.find({
    "like": { "$all": [ "hamberger", "book" ] }
    })

    复制

    上述能查找到name
    Mike
    字段,但是无法查找到其他字段,因为他们无法完全满足查询条件。

  2. $gt
    查找大于(great then)指定值的字段

    db.collection.find({
    "age": { "$gt": 18 }
    })

    复制

    上述查找age
    大于18
    的字段,不包含18

    日期
    也可直接那这个进行比较

  3. $gte
    表示不小于指定值,也就是大于等于

    db.collection.find({
    "age": { "$gte": 20 }
    })

    复制

    上述查找age
    不小于20
    的字段,所以包括等于20
    的字段

  4. $lt

    与$gt操作符相反,表示小于(less then)指定值

    db.collection.find({
    "age": { "$lt": 20 }
    })

    复制

    上述查找age
    小于20
    的字段,且不包含20

  5. $lte
    表示不大于指定值,也就是小于等于

    db.collection.find({
    "name": { "$lte": 18 }
    })

    复制

    上述查找age
    小于18
    的字段,且包含18

  6. $in

    查找存在指定数组中的值的数据项,与$all不同的是,字段只需要满足其中任意一项即可

    db.collection.find({
    "age": { "$in": [ 18, 20 ] }
    })

    复制

    上述可以找到所有在age
    字段等于18
    20
    的数据

  7. $nin

    与上面的$in操作符相反,表示查找不存在指定数组中的值的项

    db.collection.find({
    "like": { "$nin": [ "tv" ] }
    })

    复制

    上述查找like
    字段中不存在tv
    的项

  8. $ne

    有相等就有不相等,这个操作符就是查找不等于指定值得项,相当于只有一项的$nin

    db.collection.find({
    "like": { "$ne": "book" }
    })

    复制

    上述查找like
    字段中不存在book
    的项

  9. $and
    查找同时满足所有指定条件的项,并且至少需要包含两个条件

    db.collection.find({
    "$and": [
    {
    "name": "Mike"
    },
    {
    "age": 18
    }
    ]
    })

    复制

    上述查找name
    Mike
    并且age
    20
    的字段

  10. $nor

    与上面的$and相反,表示查找同时不满足所有指定条件的项,同样至少需要包含两个条件

    db.collection.find({
    "$nor": [
    {
    "name": "Mike"
    },
    {
    "age": 18
    }
    ]
    })

    复制

    上述查找name
    不为Mike
    并且age
    不等于18
    的数据

  11. $not
    指定不能满足指定条件的数据项,此操作符只能包含一个条件,而且它无法单独完成查询,需要与其他操作符配合一起使用。

    db.collection.find({
    "age": {
    "$not": { "$gt": 18 }
    }
    })

    复制

    上述查找age
    字段小于等于18
    的数据项,当然像例子这样的情况也可以直接使用$lte
    操作符完成。

  12. $or
    表示查找能至少满足一个条件的项,并且需要至少包含两个筛选条件

    db.collection.find({
    "$or": [
    {
    "name": "Mike"
    },
    {
    "age": 20
    }
    ]
    })

    复制

    上述表示查找name
    Mike
    或者age
    20
    的数据项

  13. $exists
    此操作符用于字段的key
    的判断,表示查找是否存在否字段key
    的数据项,可选值为true
    false
    ,选择true表示存在,false则不存在指定字段的项  

    db.collection.find({
    "name": { "$exists": true }
    })

    复制

    上述查找存在name
    字段的数据项

  14. $mod
    表示查找满足计算结果的数据项,此操作符为取模

    db.collection.find({
    "age": { "$mod": [ 3, 0 ] }
    })

    复制

    上述表示age
    字段的值对3取模等于0的值。

  15. $type
    表示选择指定数据类型的数据项

    db.collection.find({
    "name": { "$type": "string" }
    })

    复制

    上述查找name
    字段值类型为string
    的数据项
    此操作符表示能查找对应的数据类型的数据项,它也有对应的代码,如下所示

    Double: 1
    String
    Object 3
    Array 4
    Binary data 5
    Undefined 6 已废弃。
    Object id 7
    Boolean 8
    Date 9
    Null 10
    Regular Expression 11
    JavaScript 13
    Symbol 14
    JavaScript (with scope) 15
    32-bit integer 16
    Timestamp 17
    64-bit integer 18
    Min key 255 Query with -1.
    Max key 127

  16. $regex
    就是字面意思,使用正则表达式来匹配字段

    db.collection.find({
    "name": { "$regex": /mike/, "$options": "i" }
    })

    复制

    上述匹配name
    字段值包含mike
    (不区分大小写是因为配置了$options
    )的数据项
    $options
    表示正则表达式的修饰符,其他的还有i
    (不区分大小写),g
    (全局匹配),m
    (多行匹配),s
    (.包含换行符\n
    )
    当然直接使用正则表达式也是可以的。

  17. $where
    有些情况下普通方法很难做出筛选,可以使用此操作符用javascript
    语法来进行筛选

    db.collection.find({
    "$where": "this.name='Jack'&&this.like.some(key => key == 'hamberger')"
    })

    复制

    上述查找name
    Jack
    like
    字段包含hamberger
    值得数据项
    它甚至可以直接写一个函数{ function() { return this.name == 'Jack' && this.like.some(key => key == 'hamberger') } }

    注意
    虽然这种方法可以有效的解决一些问题,但是还是尽量不要使用这个操作符,因为它会将MongoDB里面保存的BSON数据变为JavaScript的语法结构,这样的方式不方便使用数据库的索引机制。

$elemMatch
此操作符用于对类似一个嵌套数组对象来进行多条件的查询
$elemMatch.png
上述查找了like
字段数组中type
eat
并且target
hamberger
的数据项



更新操作符

  1. $inc
    对一个字段增加指定数量,且字段的值类型为数字

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$inc": { age: 100 }
    })

    复制

    当然可以通过指定数字值为负数
    实现递减操作。

  2. $set
    这是相当常见的操作符,表示设置指定的key

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$set": { age: 1000 }
    })

    复制

    上述将name
    Mike
    的字段的age
    字段设置为1000

    如果key
    不存在的话则创建
    当然也可以同时设置多个值,但是需要注意的是如果修改的值之前是一个对象或一个数组的话会整个覆盖掉该值。具体的修改方法可以参照下方的具体实例。

  3. $unset

  4. 将某一个字段删除

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$unset": { "hobby": "" }
    })

    复制

    上述将name
    Mike
    的字段的hobby
    字段删除,如果不存在该字段则不进行操作

  5. $push

  6. 对某一字段进行内容追加,只能对数组字段进行操作(否则会报错),不存在则直接设置为空数组
    并添加

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$push": { "like": "book" }
    })

    复制

    上述将name
    Mike
    的字段的like
    字段设置为[ "book" ]

  7. $pushAll
    类似上面的$push
    操作符,但是接收的值时一个数组
    ,表示可同时追加多个值,同样是对数组字段进行操作

    db.collection.updateOne({
    "name": "Jack"
    }, {a
    "$pushAll": { "like": [ "tv", "sport" ] }
    })

    复制

    上述紧接前面的操作,向like
    字段中继续追加了tv
    sport

    不过似乎在高版本mongodb
    已经取消了这个操作符,有待考证。

  8. $addToSet
    类似上面的$pushAll
    操作符,不同的是,当且仅当该值在字段中不存在
    时添加,相当于是自动做了去重。

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$addToSet": { "like": [ "tv", "hamberger" ] }
    })

    复制

    继续上面的like
    添加数据,因为上面添加过tv
    字段,所以再次添加被忽略
    当然此操作符添加的值不一定是数组,也可以这样
    $addToSet: { "like": "hamberger" }

  9. $pop
    $pop
    操作符相反,表示删除指定字段的第一个或最后一个值,同样只能是数组

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$pop": { "like": 1 }
    })

    复制

    上述表示删除like
    字段的最后一个值。
    1
    表示最后一个值,-1
    表示第一个值

  10. $pull
    表示从某一字段中删除指定的值,针对数组

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$pull": { "like": "hamberger" }
    })

    复制

    上述将name
    Mike
    的字段的like
    数组中的hamberger
    字段删除

  11. pullAll
    类似$pull
    操作符,不同的是可以同时删除多个值

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$pullAll": { "like": [ "hamberger", "book" ] }
    })

    复制

    上述删除了name
    Mike
    字段的like
    中的hamberger
    book

  12. rename
    这个操作符表示对之前设置过的字段进行重命名,设置的是key

    db.collection.updateOne({
    "name": "Mike"
    }, {
    "$rename": { "like": "dislike" }
    })

    复制

    上述将like
    字段修改为了dislike
    名称。

相关实例

讲完了操作符,这里简单讲几个之前在实践当中碰到的一些问题,以及解决方法,欢迎各位参考。

  1. 查找或修改数组中嵌套的对象的属性
    假设database
    collection
    中存在以下数据

    [
    {
    "name": "Mike",
    "age": 18,
    "job": "student",
    "like": [
    {
    "type": "eat",
    "target": "hamberger"
    },
    {
    "type": "sport",
    "target": "running"
    }
    ]
    },
    {
    "name": "Jack",
    "age": 50,
    "job": "teacher",
    "like": [
    {
    "type": "eat",
    "target": "vegetable"
    },
    {
    "type": "sport",
    "target": "baseball"
    }
    ]
    }
    ]

    复制

    普通情况下无法直接选中对应数组对象的属性,但是mongodb
    中支持.
    来选择数组对象中的属性

  • parent_field.child_field

    比如像上面的like
    字段选择target=vegetable

    db.collection.find({ "like.target": "vegetable" })

  1. 修改多层嵌套的数组对象
    有时候不止会有一层嵌套,多层嵌套上面的方法不适用,虽然这种存储方式不太常见,但是也可以解决
    假设有如下的数据

  [
{
"name": "Jack",
"like": [
{
type: "eat",
target: [
{
name: "hamberger",
price: 100
},
{
name: "salad",
price: 200
}
]
}
]
}
]
//执行更新操作
db.collection.updateOne({ "name": "Jack" }, { "$set": { "like.$[stepone].target.$[steptwo].price" : 200 } }, {
arrayFilters: [
{
"stepone": {
"$type": "object"
},
"stepone.type": "eat"
},
{
"steptwo": {
"$type": "object"
}
}
]
})

复制

上述操作是选择上面数据中like
字段的type
eat
并且target
数组中的name
hamberger
的价格price
改成了200
updateOne
的第三个参数用户定义第二参数中用到的嵌套名称的筛选条件,并且它的名称定义为以小写字母开头的字母数字字符串

结束

MongoDB
的操作符以及命令远不止这些,有兴趣的可以自行去MongoDB官网查找学习,本人也会在后续的实践学习中继续更新。😸

文章转载自前端下饭师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论