Mongo shell 读取文档操作
- 官方文档地址:https://www.mongodb.com/docs/v6.0/tutorial/query-documents/
- 中文文档地址:https://mongodb.net.cn/manual/tutorial/query-documents/
命令
- db.collection.find()
- 匹配查询
- 操作操作符
游标:
- 查询操作返回的结果游标
- 游标的迭代与操作
投射
- 只返回部分字段
- 内嵌文档的投射
- 数组的投射
命令:db.<collection>.find(<query>, <projection>)
1. 既不筛选,也不投射
- db.accounts.find()
- db.accounts.find().pretty()
> db.accounts.find()
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
> db.accounts.find().pretty()
{
"_id" : {
"accoountNo" : "001",
"type" : "savings"
},
"name" : "irene",
"balance" : 80
}
{
"_id" : {
"type" : "savings",
"accoountNo" : "001"
},
"name" : "irene",
"balance" : 80
}
2. 查询选择器
https://www.mongodb.com/docs/v6.0/reference/operator/query/
比较
名称 | 描述 |
---|---|
$eq | 匹配等于指定值的值。 |
$gt | 匹配大于指定值的值。 (如果比较字符串,将按照字符排序) |
$gte | 匹配大于或等于指定值的值。 |
$in | 匹配数组中指定的任何值。 |
$lt | 匹配小于指定值的值。 |
$lte | 匹配小于或等于指定值的值。 |
$ne | 匹配所有不等于指定值的值。(不包含匹配字段的文档也会被匹配到) |
$nin | 不匹配数组中指定的任何值。 (不包含匹配字段的文档也会被匹配到) |
使用实例:{field: {$gt: value}
> db.accounts.find()
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
> db.accounts.find({name: "bob"})
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
> db.accounts.find({"_id.type": "savings"})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
> db.accounts.find({"_id.type": {$ne: "savings"}})
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
> db.accounts.find({"_id.type": {$ne: "test"}})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
逻辑
名称 | 描述 | 表达式 |
---|---|---|
\(and | 用逻辑联接查询子句AND将返回两个子句都匹配的所有文档。 |{\)and: [ { { ]} |
||
\(not | 反转查询表达式的效果,并返回与查询表达式不匹配的文档。<br>(**不包含匹配字段的文档也会被匹配到**) | {field: {\)not: { |
||
$or | 用逻辑联接查询子句OR将返回符合任一子句条件的所有文档。 当筛选条件都是 $eq时, $or 与 $in 等效 |
{$or: [ { { ]} |
|
\(nor | 用逻辑联接查询子句NOR将返回两个子句均不匹配的所有文档。 <br>(**不包含匹配字段的文档也会被匹配到**)|{\)nor: [ { { ]} |
# 读取余额不小于90的银行账户文档
> db.accounts.find({balance: {$not: {$lt:90}}})
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
# 复合主键的type 不等于 'test' 的文档
> db.accounts.find({"_id.type": {$not: {$eq: "test"}}})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
>
# 复合主键的type 不等于 'savings' 的文档
> db.accounts.find({"_id.type": {$not: {$eq: "savings"}}})
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
# and 操作
> db.accounts.find({
$and: [
{balance: {$gte:90}},
{name: {$lt: "bob"}}
]
})
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
# (不同字段)省略and操作
> db.accounts.find({
balance: {$gte:90},
name: {$lt: "bob"}
})
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
# (同一字段)省略and操作
> db.accounts.find({
balance: {$gt:80, $lt:100}
})
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
元素
名称 | 描述 | 表达式 |
---|---|---|
\(exists | 匹配具有指定字段的文档。 |{field: {\)exists: boolean }} | ||
\(type | 如果字段是指定类型,则选择文档。[BSON Types](https://www.mongodb.com/docs/v6.0/reference/bson-types/) |{field: {\)type: BSON_type }} {field: {$type: [BSON_type, BSON_type ...]}} |
> db.accounts.find({"_id.type": {$exists: true}})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
> db.accounts.find({"_id.type": {$ne: "test"}})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
> db.accounts.find({"_id.type": {$exists: true, $ne: "test"}})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
> db.accounts.find({"_id": {$type: "objectId"}})
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
> db.accounts.find({"_id": {$type: ["objectId", "object"]}})
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
# 字段为空的文档
> db.accounts.find({"name": {$type: "null"}})
评估
名称 | 描述 |
---|---|
$expr | 允许在查询语言中使用聚合表达式。 |
$jsonSchema | 根据给定的JSON Schema验证文档。 |
$mod | 对字段的值执行模运算并选择具有指定结果的文档。 |
$regex | 选择值与指定的正则表达式匹配的文档。 |
$text | 执行文本搜索。 |
$where | 匹配满足JavaScript表达式的文档。 |
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } } # 在和 $in 操作符一起使用时,只能使用这一种
> db.accounts.find({name: {$in: [ /^J/, /^k/ ] }})
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
> db.accounts.find({name: {$in: [ /^J/i, /^k/ ] }})
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
> db.accounts.find({name: { $regex: /ACK/}})
>
> db.accounts.find({name: { $regex: /ACK/, $options: 'i' }})
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
地理空间
名称 | 描述 |
---|---|
$geoIntersects | 选择与GeoJSON几何形状相交的几何形状。该2dsphere索引支持 $geoIntersects。 | |
$geoWithin | 选择边界GeoJSON几何内的几何。该2dsphere和2D指标支持 $geoWithin。 | |
$near | 返回点附近的地理空间对象。需要地理空间索引。该2dsphere和2D指标支持 $near。 | |
$nearSphere | 返回球体上某个点附近的地理空间对象。需要地理空间索引。该2dsphere和2D指标支持 $nearSphere。 |
数组
名称 | 描述 |
---|---|
$all | 匹配数组字段中包含所有查询值的文档 |
$elemMatch | 匹配数组字段中至少存在一个值满足筛选条件的文档 |
$size | 如果数组字段为指定大小,则选择文档。 |
> db.accounts.find()
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
# $all -> { <field>: { $all: [ < > , <value2> ... ] } }
> db.accounts.find({contact: { $all: ["Alabama", "US"] }})
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
> db.accounts.find({contact: { $all: [[ "222", "333" ]] }})
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
# $elemMatch -> { <field>: { $elemMatch: { <query1>, <query2>, ... } } }
> db.accounts.find({contact: { $elemMatch: {$gte: "110", $lte: "120" }}})
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
# $all 和 $elemMatch 结合
# 查询 contact 中包含一个等于 "111" 和 一个等于 "US" 的文档
> db.accounts.find({
contact: { $all: [
{$elemMatch: {$eq: "111"}},
{$elemMatch: {$eq: "US"}},
]}
})
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
按位
名称 | 描述 |
---|---|
$bitsAllClear | 匹配其中一组位位置的数值或二进制值都具有值0。 |
$bitsAllSet | 匹配其中一组位位置的数值或二进制值都具有值1。 |
$bitsAnyClear | 匹配数字或二进制值,其中一组位位置中的任何位的值为0。 |
$bitsAnySet | 匹配数字或二进制值,其中一组位位置中的任何位的值为1。 |
注释
名称 | 描述 |
---|---|
$comment | 向查询谓词添加注释。 |
3. 投影算子
名称 | 描述 |
---|---|
$ | 在与查询条件匹配的数组中投影第一个元素。 |
\(elemMatch | 投影与指定\)elemMatch条件匹配的数组中的第一个元素。 | |
\(meta | 投影\)text操作期间分配的文档分数。 | |
$slice | 限制从数组投影的元素数量。支持跳过和限制切片。 |
文档游标
- db.collection.find() 返回一个文档集合游标
- 在不迭代游标的情况下,只列出前20个文档
- 可以直接使用游标下标直接访问文档集合中的某一个文档
- 遍历完游标中所有的文档后,或者在10分钟后,游标将自动关闭
- 可以使用noCursorTimeout()函数来保持游标一直有效, 在这之后,在不遍历的情况下,需要主动关闭游标
> var myCursor = db.accounts.find()
> myCursor
{ "_id" : { "accoountNo" : "001", "type" : "savings" }, "name" : "irene", "balance" : 80 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
>
> myCursor
>
> var myCursor = db.accounts.find()
> myCursor[2]
{
"_id" : ObjectId("6327179289c04594a4b8f675"),
"name" : "bob",
"balance" : 100
}
> myCursor[1]
{
"_id" : {
"type" : "savings",
"accoountNo" : "001"
},
"name" : "irene",
"balance" : 80
}
> var myCursor = db.accounts.find().noCursorTimeout()
> myCursor.close()
游标所有的方法:
- https://www.mongodb.com/docs/v6.0/reference/method/db.collection.find/#available-mongosh-cursor-methods
- https://mongodb.net.cn/manual/reference/method/js-cursor/
游标函数 | 描述 |
---|---|
cursor.hasNext() | 如果游标包含文档并且可以迭代,则返回true。 |
cursor.next() | 返回游标中的下一个文档。 |
cursor.forEach() | 对光标中的每个文档应用JavaScript函数 |
cursor.limit() | 和SQL中 limit 一样,注意: cursor.limit(0) 返回全部 |
cursor.skip() | 和SQL中 offset 一样,返回一个游标,该游标仅在通过或跳过多个文档后才开始返回结果 |
cursor.count() | 修改光标以返回结果集中的文档数,而不是文档本身 |
cursor.sort() | 返回根据排序规范排序的结果。 |
cursor.close() | 关闭游标并释放关联的服务器资源 |
cursor.allowDiskUse() | |
cursor.allowPartialResults() | |
cursor.batchSize() | |
cursor.isClosed() | |
cursor.collation() | |
cursor.comment() | |
cursor.explain() | |
cursor.hint() | |
cursor.isExhausted() | |
cursor.itcount() | |
cursor.map() | |
cursor.max() | |
cursor.maxTimeMS() | |
cursor.min() | |
cursor.noCursorTimeout() | |
cursor.objsLeftInBatch() | |
cursor.pretty() | |
cursor.readConcern() | |
cursor.readPref() | |
cursor.returnKey() | |
cursor.showRecordId() | |
cursor.size() | |
cursor.tailable() | |
cursor.toArray() |
# sort -> { field: ordering }
# 在sort参数中指定要作为排序依据的一个或多个字段,以及的值1或-1分别指定升序或降序排序。
> db.accounts.find().sort({balance: -1, name: -1})
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob", "balance" : 100 }
{ "_id" : ObjectId("6329d655f5bd549a110fc5d1"), "name" : "clice", "balance" : 90 }
{ "_id" : ObjectId("6329d648f5bd549a110fc5d0"), "name" : "blice", "balance" : 90 }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice", "balance" : 90 }
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene", "balance" : 80 }
注意游标函数执行顺序:
- 无论语句的位置顺序如何,最终结果将会按照语句的优先级顺序执行: cursor.sort() > cursor.skip() > cursor.limit()
文档投影
命令:db.<collection>.find(<query>, <projection>)
-
<query>
定义读取文档的筛选条件, 使用 查询运算符 指定选择过滤器 -
<projection>
定义读取文档结果 投影不使用投影时,db.collection.find()返回符合筛选条件的完整文档。
除了文档主键之外,我们不可以在投影文档中混合使用包含和不包含这两种投影。
\(slice 操作符可以返回数组字段中的部分元素 \)elemMatch 和 $ 操作符可以返回数组字段中满足筛选条件的第一个元素, 注意 $ 作为操作符时,表示投影的筛选条件和 query 中相应字段的筛选条件一致,下面有例子
> db.accounts.find({}, {"name": 1})
{ "_id" : { "type" : "savings", "accoountNo" : "001" }, "name" : "irene" }
{ "_id" : ObjectId("6327179289c04594a4b8f675"), "name" : "bob" }
{ "_id" : ObjectId("632717a889c04594a4b8f676"), "name" : "alice" }
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen" }
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack" }
{ "_id" : ObjectId("6329d648f5bd549a110fc5d0"), "name" : "blice" }
{ "_id" : ObjectId("6329d655f5bd549a110fc5d1"), "name" : "clice" }
>
>
> db.accounts.find({}, {"name": 1, "_id": 0})
{ "name" : "irene" }
{ "name" : "bob" }
{ "name" : "alice" }
{ "name" : "karen" }
{ "name" : "jack" }
{ "name" : "blice" }
{ "name" : "clice" }
> db.accounts.find({}, {"name": 0, "_id": 0})
{ "balance" : 80 }
{ "balance" : 100 }
{ "balance" : 90 }
{ "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
{ "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
{ "balance" : 90 }
{ "balance" : 90 }
> db.accounts.find({}, {"name": 1, "balance": 0})
Error: error: {
"ok" : 0,
"errmsg" : "Cannot do exclusion on field balance in inclusion projection",
"code" : 31254,
"codeName" : "Location31254"
}
# $slice 操作符可以返回数组字段中的部分元素
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: 1}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ [ "222", "333" ] ] }
{ "name" : "jack", "contact" : [ "111" ] }
>
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: 2}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ [ "222", "333" ], "Beijing" ] }
{ "name" : "jack", "contact" : [ "111", "Alabama" ] }
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: -1}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ "China" ] }
{ "name" : "jack", "contact" : [ "US" ] }
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: -2}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ "Beijing", "China" ] }
{ "name" : "jack", "contact" : [ "Alabama", "US" ] }
# {$slice: [1, 2]} 表示跳过数组中的第 1 个元素后,返回 2 个元素
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: [1, 2]}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ "Beijing", "China" ] }
{ "name" : "jack", "contact" : [ "Alabama", "US" ] }
# {$slice: [1, 2]} 表示跳过数组中的第 1 个元素后,返回 1 个元素
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: [1, 1]}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ "Beijing" ] }
{ "name" : "jack", "contact" : [ "Alabama" ] }
# {$slice: [1, 2]} 表示跳过数组中的第 2 个元素后,返回 1 个元素
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$slice: [2, 1]}}).sort({contact: -1}).limit(2)
{ "name" : "karen", "contact" : [ "China" ] }
{ "name" : "jack", "contact" : [ "US" ] }
# $elemMatch 和 $ 操作符可以返回数组字段中满足筛选条件的第一个元素, 注意 $ 作为操作符时,表示投影的筛选条件和 query 中相应字段的筛选条件一致
> db.accounts.find({}, {"_id": 0, "name": 1, "contact": {$elemMatch: {$gt: "Alabama"}}})
{ "name" : "irene" }
{ "name" : "bob" }
{ "name" : "alice" }
{ "name" : "karen", "contact" : [ "Beijing" ] }
{ "name" : "jack", "contact" : [ "US" ] }
{ "name" : "blice" }
{ "name" : "clice" }
> db.accounts.find({contact: {$gt: "Alabama"}})
{ "_id" : ObjectId("632873b543489401f4ff49c2"), "name" : "karen", "balance" : 250, "contact" : [ [ "222", "333" ], "Beijing", "China" ] }
{ "_id" : ObjectId("63287530f8526f895273d037"), "name" : "jack", "balance" : 1000, "contact" : [ "111", "Alabama", "US" ] }
>
> db.accounts.find({contact: {$gt: "Alabama"}}, {"_id": 0, "name": 1, "contact.$": 1})
{ "name" : "karen", "contact" : [ "Beijing" ] }
{ "name" : "jack", "contact" : [ "US" ] }
标签:name,MongoDB,db,笔记,find,contact,文档,balance,id
From: https://www.cnblogs.com/guohewei/p/16783141.html