21

MongoDB 常用查询操作

 4 years ago
source link: https://ytao.top/2020/06/14/27-mongodb-query/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

6zInIfy.jpg!web

MongoDB 查询操作可实现大部分关系型数据库的常用查询操作,本文对 MongoDB 常用查询进行讲解。

在阅读本文前,推荐先阅读 《MongoDB 安装及文档的基本操作》

在进行操作讲解前,先展示当前 MongoDB 中已存在的文档,集合名称 article
QnAnqm2.png!web

条件大小比较操作

查询文档时,对条件的大小、范围进行过滤查询,以下是常用比较操作符

操作符 说明 $eq 查询与条件值相等的文档,类似关系型数据库的 = $ne 查询与条件值不相等或不存在的文档,类似关系型数据库的 != $gt 查询大于条件值的文档,类似关系型数据库的 > $gte 查询大于或等于条件值的文档,类似关系型数据库的 >= $lt 查询小于条件值的文档,类似关系型数据库的 < $lte 查询小于或等于条件值的文档,类似关系型数据库的 <= $in 查询 $in 数据里值的文档,类似关系型数据库的 in $nin 与 $in 查询相反,类似关系型数据库的 not in

由于使用大于、小于、等于关系都差不多,比较好理解,这里就举一个例子说明,使用 $gte 来获取大于或等于 150 的 visitor

db.article.find({"visitor": {$gte:150}})

执行结果:

7rmQje7.png!web

使用 $in 时,必须用数组来设置条件值,比如获取 visitor 为 70150 的值

db.article.find({"visitor": {$in:[70, 150]}})

执行结果:

mUnamyN.png!web

逻辑操作符

多条件查询中,条件与条件连接符号叫做逻辑操作符。常用操作符:

操作符 说明 $and 表示所有条件同时满足时成立 $nor 与 $and 相反,所有条件都不满足时成立 $or 只要有一个条件满足则成立 $not 表示字段存在并且不符合条件

$and 查询 author=ytaovisitor=150 的文档

db.article.find(
    {$and:[
      {"author":{$eq:"ytao"}},
      {"visitor":{$eq:150}}
    ]}
)

$nor 查询不是 author=ytao 和不是 visitor=170 的文档

db.article.find(
    {$nor:[
      {"author":{$eq:"ytao"}},
      {"visitor":{$eq:170}}
    ]}
)

$or 查询 author=ytaovisitor=170 的文档

db.article.find(
    {$or:[
      {"author":{$eq:"ytao"}},
      {"visitor":{$eq:170}}
    ]}
)

$not 查询不是 author=ytao 的文档

db.article.find(
    {"author":{$not:{$eq:"ytao"}}}
)

元素操作符

对字段元素上的操作符叫做元素操作符

操作符 说明 $exists 判断文档中字段是否存在, true 为存在, false 为不存在 $type 筛选指定字段类型的文档

$exists 查询 author 字段存在的文档

db.article.find(
    {"author":{$exists:true}}
)

$type 查询 author 字段为数组的文档

db.article.find(
    {"author":{$type:"array"}}
)

正则表达式

MongoDB 支持正则表达式匹配文档,通过正则表达我们可以实现关系型数据库的模糊查询,以及更加强大匹配规则,其使用语法有三种:

{ < field >: { $regex: /pattern/, $ options : '<options>' } }
{ < field >: { $regex: 'pattern', $ options : '<options>' } }
{ < field >: { $regex: /pattern/<options> } }

参数 /pattern/'pattern' 都是表示正则表达式,直接添加字符串可用来模糊查询。

参数 $options 为可选参数,有四个固定值选择

options 选项 说明 i 匹配过程忽略大小写 x 匹配过程忽略空格 m 匹配多行数据,但都是从每行的起点和结尾匹配 s 将多行转换成一行后进行匹配,可匹配换行符 \n 字符串

模糊查询 authorTao 的示例:

db.article.find(
    {"author":{$regex:/Tao/, $options:'i'}}
)

查询结果

3Yj2qme.png!web

从上面查询结果中可以看到,数据格式也可以进行匹配到。

聚合操作

聚合操作可以实现分组、排序、分页、多集合关联查询等,使用语法格式:

db.collection.aggregate([
    {聚合操作一},
    {聚合操作二}
])

条件筛选

$match用来进行条件筛选,可以使用一些条件限制来进行查询。

语法格式:

db.article.aggregate([
    { $match: <条件> }
])

查询 author = ytaovisitor > 100 的文档

db.article.aggregate([
    { $match: {
        $and: [
            {"author": {$eq: "ytao"}},
            {"visitor": {$gt: 100}}
        ]} 
    }
])

分组操作

$group是分组操作符,类似于关系型数据库中的 group by 操作。其语法格式为:

db.collection.aggregate([
    {
        $group:{
            "_id":"$<分组字段名>", 
            <显示结果的字段名称>:{<运算符>:"$<运算符计算的字段名>"}
        }
    }
])

其中运算符如下:

运算符 说明 $avg 当前组的平均数 $sum 当前组的总和 $min 当前组的最小值 $max 当前组的最大值 $first 当前组的第一个的值 $last 当前组的最后一个的值 $push 数组形式展示指定的当前组字段值 $addToSet 数组形式展示指定的当前组字段不重复值

分组求出每个 authorvisitor 平均数的例子

db.article.aggregate([
    {
        $group:{
            "_id":"$author", 
            "avg_visitor":{$sum:"$visitor"}
        }
    }
])

字段显示

指定查询后返回的字段使用 $project ,字段指定默认值为 0 ,但是 _id 默认为 1 ,显示指定字段语法为:

db.collection.aggregate([
    {
        $project:{
            "<字段名>": <0或1>, 
            "<字段名>":<0或1>
        }
    }
])

展示 titlevisitor 字段示例:

db.article.aggregate([
    {
        $project:{
            "_id": 0, 
            "title": 1,
            "visitor": 1
        }
    }
])

同时, $project 还以搭配 $split (字符串拆分)、 $substr (截取字符串)、 $concat (合并字符串)、 $switch (条件判断)、 $toLower (转换成小写)、 $toUpper (转换成大写)、时间格式处理等等操作符进行操作,语法为:

db.collection.aggregate([
    {
        $project:{
            "<字段名>": {<操作符>: <条件>}, 
            "<字段名>": {<操作符>: <条件>},
        }
    }
])

例如将 title 中的字母都转换成大写

db.article.aggregate([
    {
        $project:{
            "titleField":{ $toUpper:"$title" }
        }
    }
])

返回结果

Z7rqEzf.png!web

排序操作

$sort是文档排序操作符,类似关系型数据中的 order by 指令。 $sort 排序用 1-1 表示正序和倒序。

语法格式:

db.collection.aggregate([
    {
        $sort:{
            "<排序字段名>": <1 或 -1>
        }
    }
])

visitor 字段名进行倒序排序:

db.article.aggregate([
    {
        $sort:{
            "visitor": -1
        }
    }
])

排序结果

3MVRvye.png!web

分页操作

分页使用 $skip$limit 进行分页操作。 $skip 表示跳过文档的数量, $limit 表示返回的文档数量,这两个指令使用,类似于关系型数据中的 limit <start>, <size> 分页操作。

语法格式:

db.collection.aggregate([
    {$skip: <跳过的文档数量>},
    {$limit: <返回的文档数量>}
])

查询第二页的两条数据示例:

db.article.aggregate([
    {$skip: 2},
    {$limit: 2}
])

返回结果

Qn6J7jv.png!web

统计文档数量

$count用来统计文档数量,进行条件筛选时。

语法格式:

db.collection.aggregate([
    { $count: "<显示数量的字段的名称>" }
])

统计全部文档数量:

db.article.aggregate([
    { $count: "数量" }
])

统计结果:

6vMVfmb.png!web

多集合关联查询

$lookup是用来多集合关联查询时使用的,类似于关系型数据库中的联表查询。

使用语法:

db.collection.aggregate([
    { 
        $lookup: {
            from: <关联的表名>,
            localField: <当前表的关联字段>,
            foreignField: <关联表的关联字段>,
            as: <另一集合嵌入的字段名>
        }
    }
])

在进行多集合关联查询演示前,先添加一个集合 person ,里面添加一条数据:

NbMRreb.png!web

查询 age = 18 的集合:

db.article.aggregate([
    { 
        $lookup: {
            from: "person",
            localField: "author",
            foreignField: "author",
            as: "person_info"
        }
    },
    {
       $match:{
           "person_info.age": {$eq: 18}
       }
    }
])

返回结果:

bu63M32.png!web

总结

对 MongoDB 的常用查询操作进行了解后,可以发现它和关系型数据操作有很多类似的操作思想。对于这些操作的使用,相对也是较为灵活,提供的 API 也是较为强大,几乎能满足大部分使用场景的检索要求。掌握这些查询操作,可以更高效的获取 MongoDB 中的文档。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK