前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Not Only SQL (四) - MongoDB Introduce & CRUD (中)

Not Only SQL (四) - MongoDB Introduce & CRUD (中)

作者头像
RiemannHypothesis
发布2022-08-19 16:48:58
1.2K0
发布2022-08-19 16:48:58
举报
文章被收录于专栏:Elixir

一、读取文档

读取文档命令

代码语言:javascript
复制
db.<collection>.find({<query>,<projection>})
  • <query>:定义读取操作时筛选文档的条件
  • <projection>:定义了对读取结果进行投射 这两个条件都不是必填的
代码语言:javascript
复制
// 查询所有文档
db.accounts.find()
image.png
image.png
代码语言:javascript
复制
// 查询所有文档,优化显示格式
db.accounts.find().pretty()
image.png
image.png

匹配查询

代码语言:javascript
复制
// 查询name为banner的文档
db.accounts.find({name: "banner"})

// 查询name为banner、balance为1000的文档
db.accounts.find({name: "banner", balance: 1000})

使用复合主键进行匹配查询

image.png
image.png

使用比较操作符查询

代码语言:javascript
复制
db.<collection>.find({<field>: {$<operator>: <value>}})
  • <field>:比较的字段
  • $<operator>:比较操作符
  • <value>:比较的值

比较操作符主要有

  • $eq:匹配字段值相等的文档
  • $ne:匹配字段值不等的文档
  • $gt:匹配字段值大于查询值的文档
  • $gte:匹配字段值大于等于查询值的文档
  • $lt:匹配字段值小于查询值的文档
  • $lte:匹配字段值小于等于查询值的文档
代码语言:javascript
复制
// 读取name等与banner的文档
db.accounts.find({
    name: {$eq: "banner"}
})

plus:使用$eq可以与之前使用匹配查询达到相同的想过

代码语言:javascript
复制
// 读取name不等与banner的文档
db.accounts.find({
    name: {$ne: "banner"}
});

// 读取balance不等于100的文档
db.accounts.find({
    balance: {$ne: 1000}
});

plus:$ne也会筛选出不包含查询字段的文档

代码语言:javascript
复制
// 读取balance大于100的文档
db.accounts.find({
    balance: {$gt: 100}
});

// 读取name在ban之后的文档
db.accounts.find({
    name: {$gt: "ban"}
});

$in:匹配字段值与任意查询值相等的文档

$nin:匹配字段值与任何查询值都不想等的文档

代码语言:javascript
复制
// 读取name为banner、strange、peter的文档
db.accounts.find({
    name: {$in: ["banner", "strange", "peter"]}
})

// 读取name为banner、peter之前的其他文档
db.accounts.find({
    name: {$nin: ["banner", "peter"]}
})

plus:$nin会筛选出并不包含查询字段的文档

使用逻辑操作符查询

代码语言:javascript
复制
db.<collection>.find(<field>: {$<operator>: {<operator-expression>}})
  • <field>:比较的字段
  • $<operator>:逻辑操作符
  • <operator-expression>:逻辑表达式

逻辑操作符主要有

  • $not:匹配筛选条件不成立的文档
  • $and:匹配筛选条件全部成立的文档
  • $or:匹配至少一个筛选条件成立的文档
  • $not:匹配多个筛选条件全都不成立的文档
代码语言:javascript
复制
// 查询余额不小于500的文档
db.accounts.find({balance: {$not: {$lt: 100}}})

$not也会筛选出不包含查询字段的文档

代码语言:javascript
复制
// 查询_id.type不是saving的文档
db.accounts.find({"_id.type": {$not: {$eq: "saving"}}})

$and操作符后可以是一个条件的数组

代码语言:javascript
复制
db.<collection>.find({$and: [{<operator-expression1>}, <operator-expression2>}, <operator-expression3>}, .... ]})
代码语言:javascript
复制
// 查询余额大于100并且用户姓名排在banner之后的文档
db.accounts.find({
    $and:[
        {"balance": {$gt: 100}},
        {"name": {$gt: "banner"}}
    ]
})

不管是在同一字段还是不同字段,$and操作符可以省略

代码语言:javascript
复制
db.accounts.find({
    balance: {$lt: 50000, $gt: 100}
})

db.accounts.find({
    balance: {$gt: 100},
    name: {$gt: "banner"}
})
代码语言:javascript
复制
// 查询name等与banner或者balance小于1000的文档
db.accounts.find({
    $or: [
        {name: {$eq: "banner"}},
        {balance: {$lt: 1000}}
    ]
});
// 查询balance大于500或者小于1000的文档
db.accounts.find({
    $or: [
        {balance: {$gt: 500}},
        {balance: {$lt: 1000}}
    ]
});

plus:当筛选条件使用的都是eq操作符时,or和

$nor操作符后可以是一个条件的数组

代码语言:javascript
复制
db.<collection>.find({$nor: [{<operator-expression1>}, <operator-expression2>}, <operator-expression3>}, .... ]})
代码语言:javascript
复制
// 查询name不是banner和peter且balance不为1000的文档
db.accounts.find({
    $nor: [
        {name: "banner"},
        {name: "peter"},
        {balance: 1000}
    ]
})

plus:$nor也会筛选出不包含查询字段的文档

使用字段操作符查询

代码语言:javascript
复制
db.<collection>.find({
    <field>: {$exists: <boolean>}
})
  • $exists:匹配包含查询字段的文档
  • $type:匹配字段类型符合查询值的文档
代码语言:javascript
复制
// 查询文档主键存在type字段的文档
db.accounts.find({
    "_id.type": {$exists: true}
});

// 查询文档主键中type不是checking的文档,结果中会包含主键没有type字段的文档
db.accounts.find({
    "_id.type": {$ne: "checking"}
});

// 查询文档主键中type字段不是checking,但是type字段存在的文档
db.accounts.find({
    "_id.type": {$ne: "checking", $exists: true}
})
代码语言:javascript
复制
db.<collection>.find({
    <field>: {$type: <BSON type>}
})
代码语言:javascript
复制
// 查询id的type为string的文档
db.accounts.find({
    "_id": {$type: "string"}
});

使用数组操作符查询

代码语言:javascript
复制
db.<collection>.find({
    <field>: {$all: [<val1>,<val2>,<val3>]}
})
  • $all:匹配数组字段中包含所有查询值的文档
  • $elemMatch:匹配数组字段中至少存在一个值满足筛选条件的文档

先插入包含数组和嵌套数组的文档

image.png
image.png
代码语言:javascript
复制
// 查找contract地址为CHN Shanghai的文档
db.accounts.find({
  contact:{$all: ["CHN","Shanghai"]}
})
image.png
image.png
代码语言:javascript
复制
db.<collection>.find({
    <field>: {$elemMath: {<query1>,<query2>,<query3>...}}
})
代码语言:javascript
复制
// 查询联系电话范围为1000000至200000000之间的文档
db.accounts.find({
    contact: {$elemMathc: {$gt: "10000000", $lt: "200000000"}}
})
代码语言:javascript
复制
// 查询一个在100000000至200000000和一个在200000000至300000000之间的联系电话的文档
db.accounts.find({
    contact: {$all: [
        {$elemMath: {$gt: "100000000", $lt: "200000000"}},
        {$elemMath: {$gt: "200000000", $lt: "300000000"}}
    ]}
})

使用运算操作符查询

代码语言:javascript
复制
db.<collection>.find({
    <field>: {: /pattern/, : '<options>'}
})
代码语言:javascript
复制
db.<collection>.find({
    <field>: {: /pattern/<options> }
})

在和$in操作符一起使用时只能使用/pattern/<options>

代码语言:javascript
复制
// 查询name以j和c开头的文档
db.accounts.find({
    name: {$in: [/^c/,/^j/]}
})
代码语言:javascript
复制
// 查询name包含NNER的文档,忽略大小写
db.accounts.find({
    name: {$regex: /NNER/, $options: 'i'}
})

$options:i 表示不区分大小写

文档游标

查询文档操作会返回结果游标,利用游标的迭代可以进行排序和计数等操作

在不迭代游标的情况下,只列出前20个文档

代码语言:javascript
复制
var myCursor = db.accounts.find();
// 列出前20个文档
myCursor
image.png
image.png

可以使用游标的下标访问文档集合中的某一个文档

image.png
image.png

游历完游标中的所有文档或者在10分钟后,游标会自动关闭。如果想要游标一直有效可以使用noCursorTimeout()函数来保持游标一直有效,但是需要调用close()函数主动关闭游标

除了noCursorTimeout()和close()函数外有,游标还有以下这些函数可以调用

  • hasNext():是否有含有下一个文档,返回布尔值,可以作为while循环的条件
  • next():获取游标指向的下一个文档,与hasNext()搭配使用
  • forEach():遍历游标
  • limit():指定输出数量
  • skip():指定跳过的数量
  • count():输出文档总数
  • sort():对文档集合进行排序

hasNext() 与 next()

代码语言:javascript
复制
var myCursor = db.accounts.find(
    {
    name: "strange"
  }
);
// 判断是否含有下一个文档
while(myCursor.hasNext()){
  // 打印出游标调用next()函数获取的文档
  printjson(myCursor.next())
}
image.png
image.png

forEach()

代码语言:javascript
复制
var myCursor = db.accounts.find(
    {
    name: "strange"
  }
);
myCursor.forEach(printjson)
image.png
image.png

limit() 与 skip()

代码语言:javascript
复制
cursor.limit(<number>)
cursor.skip(<offset>)
image.png
image.png

limit传入0表示不会对游标进行任何的操作,效果相当于不使用limit函数

count(<applySkipLimit>)

默认情况下<applySkipLimit>为false,即cursor.account不会考虑skip()和limit()的效果,<applySkipLimit>设置为true,则会根据limit()和skip()的效果来输出数量

image.png
image.png

不提供筛选条件时,count()函数会从集合的元数据Metadata中获取结果

image.png
image.png

sort(<document>)

<document>定义了排序的要求,1表示从小到大的正序排列,-1则表示逆序排列

代码语言:javascript
复制
// 对balance按照正序排列,余额相同的情况下按照name逆序排列
db.accounts.find().sort({balance: 1, name: -1})
image.png
image.png

输出balance的最大值和最小值

image.png
image.png

skip()的优先级高于limit()

image.png
image.png

返回文档数量为5,说明先执行的skip后执行的limit(),如果先执行的limit后执行skip(),最终输出的文档数量应该为2而不是5

sort()在skip()和limit()之前执行

image.png
image.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、读取文档
    • 读取文档命令
      • 匹配查询
        • 使用比较操作符查询
          • 使用逻辑操作符查询
            • 使用字段操作符查询
              • 使用数组操作符查询
                • 使用运算操作符查询
                  • 文档游标
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档