MongoDB之find与findOne查询详解

1 简介

使用find或者findOne函数和查询文档对数据库执行查询;
使用$条件查询实现范围查询、数据集包含查询、不等式查询以及其他一些查询;
查询将会返回一个数据库游标,游标只会在需要时才将需要的文档批量返回。

2 连接数据库

C:\Users\admin>mongo 192.168.0.221:20058/test
MongoDB shell version v3.6.4-77-gaa1af56c03
connecting to: mongodb://192.168.0.221:20058/test
MongoDB server version: 3.6.4-77-gaa1af56c03
Server has startup warnings:
2018-11-12T10:34:50.866+0800 I CONTROL  [initandlisten]
2018-11-12T10:34:50.866+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-11-12T10:34:50.866+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-11-12T10:34:50.866+0800 I CONTROL  [initandlisten]
2018-11-12T10:34:50.867+0800 I CONTROL  [initandlisten] Hotfix KB2731284 or later update is not installed, will zero-out data files.
2018-11-12T10:34:50.867+0800 I CONTROL  [initandlisten]
>

> help
        db.help()                    help on db methods
        db.mycoll.help()             help on collection methods
        sh.help()                    sharding helpers
        rs.help()                    replica set helpers
        help admin                   administrative help
        help connect                 connecting to a db help
        help keys                    key shortcuts
        help misc                    misc things to know
        help mr                      mapreduce

        show dbs                     show database names
        show collections             show collections in current database
        show users                   show users in current database
        show profile                 show most recent system.profile entries with time >= 1ms
        show logs                    show the accessible logger names
        show log [name]              prints out the last segment of log in memory, 'global' is default
        use <db_name>                set current database
        db.foo.find()                list objects in collection foo
        db.foo.find( { a : 1 } )     list objects in foo where a == 1
        it                           result of the last line evaluated; use to further iterate
        DBQuery.shellBatchSize = x   set default number of items to display on shell
        exit                         quit the mongo shell
>

3 find简介

MongoDB使用find进行查询。查询就是返回一个集合中的子集,子集的范围从0个文档到整个集合。find的第一个参数决定了要返回那些文档,这个参数是一个文档,用于指定查询条件。
空查询文档会匹配集合整体内容

db.c.find()

将批量返回集合c中所有文档。
向查询文档中添加键、值对时,就意味着限定了查询条件。
查询“age”为27的所有文档,直接将键值对写进查询文档即可

db.users.find({“age”: 27})
db.users.find({“username”: “joe”})

可以向查询文档中加入多个键值对,将过个查询条件组合在一起,这样的查询条件被解释成要同时满足所有条件:

db.users.find({“username”:”joe”, “age”: 27})

该语句的作用为查询出所有名为joe且年龄为27岁的用户

> db.salary.find({
... "map.year": "2018",
... "map.month": "06",
... "map.姓名": "范雪"
... })
{ "_id" : ObjectId("5be3ef1407cd88582649e217"), "_class" : "com.zioer.entity.FreeModel", "name" : "salary", "cname" : "工资详情", "map" : { "洞库坑道保健" : "", "职务等级" : "正师职23档", "奖励工资" :
 "", "高山海岛其他" : "", "year" : "2018", "军粮差价补贴" : "", "文职房帖" : "", "医保" : "81.0", "水电" : "44.88"} }
>

3.1 指定需要返回的键

有时候并不需要将所有的键值对都返回,遇到这种情况,可以使用find或findOne中第二个参数来指定想要的键。这样可以节省传输的数据量,又能节省客户端解码文档的时间和内存消耗。

> db.salary.find({"map.year": "2018","map.month": "06","map.姓名": "范雪"}, {"map.职资": 1, "map.工作性津贴": 1})
{ "_id" : ObjectId("5be3ef1407cd88582649e217"), "map" : { "工作性津贴" : "2680.0", "职资" : "3700.0" } }
>

可以看到默认情况下,“_id”这个键总是被返回,即便没有指定要返回这个键。
也可以用第二个参数来删掉查询结果中某些键/值对。例如不希望显示“_id”键

db.users.find({}, {“_id”:  0})

对于上述查询职资的案例,如果不显示”_id”键,则可以如下进行

> db.salary.find({"map.year": "2018","map.month": "06","map.姓名": "范雪"}, {"map.职资": 1, "map.工作性津贴": 1, "_id": 0})
{ "map" : { "工作性津贴" : "2680.0", "职资" : "3700.0" } }
>

3.2 查询条件

3.2.1 查询条件

在MySQL中可以加入的查询条件有与或非,关系运算符等,在MongoDB中也支持类似的功能。
l t ” 、 “ lt”、“ ltlte”、” g t ” 、 ” gt”、” gtgte”等就是全部的比较操作符,分别对应<,<=,>,>=。可以将其组合起来以便查找一个范围的值。
查询18~30岁的用户

db.users.find({“age”: {“$gte”: 18, “$lte”: 30}})

这样的范围查询对于日期较为有用

>start = new Date(“01/01/2007”)
>db.users.find({“registered”:{“$lte”: start}})

对于文档中的键值不等于某个特定值的情况,使用条件操作符”$ne”来表示“不相等”。

db.users.find(“username”:{“$ne”: “joe”})

3.2.2 OR查询

MongoDB中有两种方式进行OR查询,“ i n ” 可 以 用 来 查 询 一 个 键 的 多 个 值 , 而 “ in”可以用来查询一个键的多个值,而“ inor”更加通用一些,可以在多个键中查询任意的给定值。
抽奖活动的中奖号码为725, 542, 390

db.raffle.find({“ticket_no”:  {“$in”: [725, 542, 390]}})

而且“$in”非常灵活,可以指定不同类型的条件和值

db.users.find({“user_id”: [12345,  “joe”]})

与“ i n ” 相 对 的 是 条 件 操 作 符 “ in”相对的是条件操作符“ innin”,该操作符将返回与数组中所有条件都不匹配的文档。
“$or”接受一个包含所有可能条件的数组为参数。

db.raffle.find({“$or”: [{“ticket_no”: 725, {“winner”: true}}]})

3.2.3 $not

n o t ” 是 元 条 件 句 , 即 可 以 用 在 其 他 任 何 条 件 之 上 。 拿 取 模 运 算 符 “ not”是元条件句,即可以用在其他任何条件之上。拿取模运算符“ notmod”来说,该操作符将查询的值除以第一个给定值,若余数为第二个给定值,则匹配成功

db.users.find({“id_num”: {“$mod”: [5, 1]}})
db.users.find({“id_num”: {“$not”: {“$mod”: [5, 1]}}})

第二个查询会返回id_num为2,3,4,5,7,8,9,10…的文档

3.2.4 条件语义

条件语句是内层文档的键,而修改器是外层文档的键
可以对一个键应用多个条件,但是一个键不能对应多个更新修改器。

db.users.find(“age”: {“$lt”: 30, “$gt”: 20})

有一些一元操作符(meta-operator),也位于外层文档中,比如“ o r ” , “ or”, “ orand”, “$nor”

db.users.find({“$and”: [{“x”: {“$lt”: 1}}, {“x”: 4}]})

4 特定类型查询

4.1 null

null类型的行为比较奇怪,它既能匹配自身,也可以匹配不包含这个键的文档。
如果仅想匹配键值为null的文档,既要检查该键的值是否为null,同时使用“$exists”条件判断键已存在

db.c.find(“z”: {“$in”: [null], “exists”: true})

由于没有“ e q ” 操 作 符 , 所 以 使 用 等 价 的 只 有 一 个 元 素 的 “ eq”操作符,所以使用等价的只有一个元素的“ eq使in”操作符效果一样。

4.2 正则表达式

正则表达式能够有效的匹配字符串。

db.users.find({“name”: /joe/i})
db.users.find({“name”: /joey?/i})

MongoDB使用Perl兼容的正则表达式PCRE库来匹配正则表达式,任何PCRE支持的正则表达式语法都能被MongoDB接受。

4.3 查询数组

查询数组元素和查询标量值是一样的。

db.food.insert({“fruit”: [“apple”, “banana”, “peach”]})

而下面的查询会匹配该文档

db.food.find({“fruit”: “banana”})

4.3.1 $all

需要通过多个元素来匹配数组

db.food.insert({“_id”: 1, “fruit”: [“apple”, “banana”, “peach”]})
db.food.insert({“_id”: 2, “fruit”: [“apple”, “kumquat”, “orange”]})
db.food.insert({“_id”: 3, “fruit”: [“cherry”, “banana”, “apple”]})

要找到既有“apple”和“banana”的文档,可以使用“$all”来查询

> db.food.find({fruit: {"$all": ["apple", "banana"]}});
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }

>

这里的顺序无关紧要。如果数组中只有一个元素,使用“$all”和不使用就没有什么区别了。
也可以使用整个数组进行精确匹配,但是精确匹配对于缺少元素或者元素冗余的情况无法匹配

> db.food.find({fruit: ["apple", "banana"]});
>

上述的查询无任何结果返回,表明三个文档均未匹配上述查询。
这是因为不使用$all,表示使用精确匹配数组,即维持顺序,也维持数量的匹配。
要想查找特定位置的元素,需要使用key.index语法指定下标。

> db.food.find({"fruit.2": "peach"});
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
> db.food.find({"fruit.3": "peach"});
>

4.3.2 $size

“$size”对于查询数组也是非常有用的,可以用它来查询特定长度的数组。

> db.food.find({"$size": 3})
Error: error: {
        "ok" : 0,
        "errmsg" : "unknown top level operator: $size",
        "code" : 2,
        "codeName" : "BadValue"
}
> db.food.find({"fruit": {"$size": 3}})
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : 2, "fruit" : [ "apple", "kumquat", "orange" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }
>

4.3.3 $slice

find的第二个参数是可选的,可以用来指定需要返回的键。”$slice”用于返回数组中的切片。

db.blog.posts.findOne(criteria, {“comments”: {“$slice”: 10}}) 

返回一个博客文章的前十条评论

db.blog.posts.findOne(criteria, {“comments”: {“$slice”: -10}}) 

返回最后十条记录。

db.blog.posts.findOne(criteria, {“comments”: {“$slice”: [23, 10]}}) 

上述查询指定了偏移值和希望返回的元素数量,来返回元素集合中中间位置的某些结果。
上述查询会跳过前23个元素,返回第24~33个元素。

注意:除非特别声明,否则使用“ s l i c e ” 将 返 回 文 档 中 所 有 的 键 。 别 的 键 说 明 符 默 认 不 返 回 未 提 及 的 键 , 这 “ slice”将返回文档中所有的键。别的键说明符默认不返回未提及的键,这“ sliceslice”不太一样。

4.3.4 返回一个匹配的数组元素

如果知道元素的下标,name“ s l i c e ” 非 常 有 用 。 但 有 时 我 们 希 望 返 回 与 查 询 条 件 相 匹 配 的 第 一 个 数 组 元 素 。 可 以 使 用 slice”非常有用。但有时我们希望返回与查询条件相匹配的第一个数组元素。可以使用 slice使操作符得到一个匹配的元素。

db.blog.posts.find({“comments.name”: “bob”}, {“comments.$”: 1})

4.3.5 数组和范围查询的相互作用

文档中的标量(非数组元素)必须与查询条件中的每一条语句相匹配。

{“x”: {“$gt”: 10, “$lt”: 20}}

x只会匹配10与20之间的文档。但是,假如某个文档的“x”字段是一个数组,如果“x”键的某一个元素与查询条件的任意一条语句相匹配,查询条件中每条语句可以匹配不同的数组元素,name这个文档也会返回。

{“x”: 5}
{“x”: 15}
{“x”: 25}
{“x”: [5, 25]}

使用下述查询

db.test.find({“x”: {“$gt”: 10, “$lt”: 20}})

上述查询会返回数组。这表明范围会匹配任意多元素数组。
想要实现这种功能,可以使用“ e l e M a t c h ” , 该 操 作 符 要 求 M o n g o D B 同 时 使 用 查 询 条 件 中 两 个 语 句 一 组 数 组 元 素 进 行 比 较 。 注 意 “ eleMatch”,该操作符要求MongoDB同时使用查询条件中两个语句一组数组元素进行比较。注意“ eleMatch,MongoDB使eleMatch”不会匹配数组元素。

db.test.find({“x”: {“$elemMatch”: {“$gt”: 10, “$lt”: 20}}})

不会匹配任何文档。

4.4 查询内嵌文档

查询内嵌文档有两种方式:查询整个文档,或者针对其键/值对进行查询

{
	"name": {
		"first": "Joe",
		"last": "Schmoe"
	},
	"age": 45
}

4.4.1 精确匹配

若使用如下查询

>db.people.find({"name": {"first": "Joe","last": "Schmoe"}})

但是这种方式子文档必须精确匹配。如果添加了一个中间名,这个查询就不再不再可行。因为这种查询方式,查询条件必须与整个内嵌文档相匹配。而且这种查询还是与顺序相关的。

{"last": "Schmoe","first": "Joe"}

什么都匹配不到。

4.4.2 键值匹配

如果允许的话,通常只针对内嵌文档的特定键值对进行查询,这是比较好的做法。这样即便数据模式改变,也不会导致所有的查询因为要精确匹配而一下子全部挂掉。可以使用如下查询:

db.people.find({“name.first”: “Joe”, “name.last”: “Schmoe”})

查询文档可以包含点来进入内嵌文档内部。

注意: 内嵌文档的匹配,必须要整个文档完全匹配

5 $where查询

键值对时一种表达能力非常好的查询方式,但是有时候仍然无法满足。“ w h e r e ” 子 句 可 以 在 查 询 中 执 行 任 意 的 J a v a S c r i p t , 这 样 就 能 在 查 询 中 执 行 任 何 事 情 。 为 安 全 起 见 , 应 该 严 格 限 制 或 者 消 除 “ where”子句可以在查询中执行任意的JavaScript,这样就能在查询中执行任何事情。为安全起见,应该严格限制或者消除“ whereJavaScriptwhere”语句的使用。应该禁止终端用户使用任意的“ w h e r e ” 语 句 。 “ where”语句。 “ wherewhere”语句最常见的应用就是比较文档中两个键的值是否相等。

db.foo.insert({"apple": 1, "banana": 6, "peach": 3})
db.foo.insert({"apple": 8, "spinach": 4, "watermelon": 4})

希望返回两个键具有相同值得文档。第二个文档就符合该条件。可以使用如下的JavaScript语句来完成该功能。

>db.foo.find({"$where": function() {
	for (var current in this) {
		for (var other in this) {
			if (current != other && this[current] == this[other]) {
				return true;
			}
		}
	}
	return false;
}})

如果函数返回true,文档就作为结果集的一部分返回;如果返回false就不返回。
不是必要时,一定要避免使用“$where”查询,因为它们在速度上要比常规查询慢很多。
在服务器上执行JavaScript时必须注意安全性,如果使用不当,服务器端JavaScript很容易受到注入攻击。可以在启动mongod时指定—noscripting

6 游标

数据库使用游标返回find查询的执行结果。客户端对游标的实现通常能够对最终结果进行有效的控制。可以限制结果的数量,略过部分结果,根据任意键按任意顺序的组合对结果进行各种排序,或者是执行其他一些强大的操作。
使用游标的好处是一次可以查看一条结果。如果将结果放在全局变量或者就没有放在变量中,MongoDB shell会自动迭代,自动显示最开始的若干文档。
要迭代结果可以使用游标的next方法,也可以使用hasNext方法来查看游标是否还有其他结果。

> for(i=0; i<100; i++) {
... db.collection.insert({x: i})
... }
WriteResult({ "nInserted" : 1 })
> var cursor=db.collection.find();
> while(cursor.hasNext()){
... obj=cursor.next();
…do sth.
... print(obj);
... }
[object BSON]
[object BSON]
[object BSON]
[object BSON]
[object BSON]
游标类实现了JavaScript的迭代器接口,所以可以在forEach循环中使用:
>var cursor = db.people.find();
>cursor.forEach(function(x) {
		print(x);
});

调用find时,shell并不立即查询数据库,而是等待真正开始要求获得结果时才发送查询,这样在执行之前可以给查询附加额外的选项。几乎所有的游标兑现搞得每个方法都会返回游标本身。这样可以按照任意顺序组成方法链。

> var cursor=db.collection.find().skip(10).limit(1).sort({"x": -1});
> while(cursor.hasNext()){
... var obj=cursor.next();
... print(obj.x);
... }
89
>

所有这些函数均是在构造查询,而查询并没有真正执行。假设执行

cursor.hasNext()

此时查询被发往服务器,shell立刻获取前100个结果或者前4MB数据,两者中较小者。这样下次调用next或者hasNext时就不必再连接数据库获取结果。客户端用光了第一组结果,shell会在此联系数据库,使用getMore请求提取结果。getMore请求会包含一个查询标识符,向数据库询问是否还有更多的结果,如果有则返回下一批结果。这个过程会一直持续到游标耗尽或者全部返回。

6.1 limit、skip和sort

最常用的查询选项就是限制返回结果的数量,忽略一定数量的结果和排序。所有这些选项一定要在查询被发送到服务器之前指定。

> db.collection.find().limit(3);
{ "_id" : ObjectId("5bee885b4faa9f2dea9f119e"), "x" : 0 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f119f"), "x" : 1 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f11a0"), "x" : 2 }
> db.collection.find().skip(95);
{ "_id" : ObjectId("5bee885b4faa9f2dea9f11fd"), "x" : 95 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f11fe"), "x" : 96 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f11ff"), "x" : 97 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f1200"), "x" : 98 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f1201"), "x" : 99 }
>

sort接受一个对象作为参数,这个对象就是一组键值对,键对应文档的键名,值代表排序的方向。排序方向可以是1(升序),-1(降序).如果你指定了多个键,则按照这些键被指定的顺序逐个排序。

> db.collection.find().limit(3).sort({"x": 1})
{ "_id" : ObjectId("5bee885b4faa9f2dea9f119e"), "x" : 0 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f119f"), "x" : 1 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f11a0"), "x" : 2 }
> db.collection.find().limit(3).sort({"x": -1})
{ "_id" : ObjectId("5bee885b4faa9f2dea9f1201"), "x" : 99 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f1200"), "x" : 98 }
{ "_id" : ObjectId("5bee885b4faa9f2dea9f11ff"), "x" : 97 }
>

由以上的结果,可以看出,程序先执行了排序,然后限制返回的结果为3条。.
要按照 “username”升序及“age”降序,可以这样写:

db.c.find.sort({“username”: 1, age: -1})

3个方法对于分页非常有用。

>db.stock.find({“desc”: “mp3”}).limit(50).sort({“price”: -1})

6.2 避免使用skip略过大量结果

用skip略过少量的文档还是不错的。但是要是数量非常多的情况下,skip会变得很慢,因为要先找到需要被略过的数据,然后再抛弃这些数据。所以结论是要尽量避免略过太多的数据。通常可以利用上次的结果来计算下一次的查询条件。

6.2.1 不用skip对结果分页

最简单的方法是用limit返回结果的第一页,然后将每个后续页面作为相对于开始的偏移量返回
//不要这么做

>var page1=db.foo.find(criteria).limit(100)
>var page2=db.foo.find(criteria).skip(100).limit(100)
>var page3=db.foo.find(criteria).skip(200).limit(100)

一般可以用排序的方式实现相同的功能,同时避免使用skip大量文档。例如使用排序

var page1=db.foo.find(criteria).sort({“date”: -1}).limit(100);

可以利用最后一个文档中的“date”值作为查询条件来获取下一页

var latest=null
//显示第一页
while (page1.hasNext) {
	latest = page1.next();
	print(latest);
}
//获取下一页
var page2 = db.foo.find({“date”: {“$gt”: latest.date}});
page2.sort({“date”: -1}).limit(100)

这样查询中就没有了skip

6.2.2 随机选取文档

从集合中挑选一个文档算是常见的问题。最笨的方法就是先计算文档总数,然后选择一个从0到文档数量之间的随机数,利用find做一次查询,略过随机数name多的文档,这个随机数的取值范围为0到集合中文档的总数。

>//不要这么做
>var total = db.foo.count()
>var random=Math.floor(Math.random()*total);
>db.foo.find().skip(random).limit(1)

这种选取随机文档的效率太低。
可以通过在插入文档时给每个文档都添加一个额外的随机数来解决。
Math.random()产生0~1的随机数

>db.people.insert({“name”: “joe”, “random”: Math.random()})
>db.people.insert({“name”: “john”, “random”: Math.random()})
>db.people.insert({“name”: “jim”, “random”: Math.random()})

这样想要从集合中随机选择一个文档,只要计算一个随机数并将其作为查询条件就行

var random = Math.random()
result=db.findOne({“random”: {“$gt”: random}})
if(null == result) {
		result=db.findOne({“random”: {“$lt”: random}})
}

上述代码对随机数大于之前所有的随机数的情况也进行了规避。

7 数据库命令

在数据操作,管理以及监控中,数据库命令都是非常有用的。例如删除集合使用“drop”数据库命令完成

> show dbs;
admin    0.078GB
config   0.078GB
local    0.078GB
test     0.078GB
test2    0.078GB
tiaoshi  0.078GB
> use test;
switched to db test
> show collections;
achievemanage
achievemanage_bak
applyCar
attendance_2018_09
attendancerules

可以执行如下的数据库命令来删除collection集合

> db.runCommand({"drop": "collection"});
{ "ns" : "test.collection", "nIndexesWas" : 1, "ok" : 1 }
>
> db.runCommand({"getLastError", 1});
2018-11-17T09:26:07.722+0800 E QUERY    [thread1] SyntaxError: missing : after property id @(shell):1:29
> db.runCommand({getLastError, 1});
2018-11-17T09:26:30.049+0800 E QUERY    [thread1] SyntaxError: missing : after property id @(shell):1:30
> db.runCommand({getLastError: 1});
{
        "connectionId" : 1593,
        "n" : 0,
        "syncMillis" : 0,
        "writtenTo" : null,
        "err" : null,
        "ok" : 1
}
>

也许对于shell辅助函数更加熟悉,这些辅助函数封装数据库命令,并提供更加简单的接口:

db.collection.drop()

注意getLastError没有双引号。
在shell中运行db.listCommands()可以看到所有的数据库命令

>db.listCommands();
…
unsetSharding:  adminOnly  slaveOk
  internal

update:
  update documents

updateRole:
  Used to update a role


updateUser:
  Used to update a user, for example to change its password


usersInfo:
  Returns information about users.


validate:  slaveOk
  Validate contents of a namespace by scanning its data structures for correctness.  Slow.
  Add full:true option to do a more thorough check
  Add scandata:false to skip the scan of the collection data without skipping scans of any indexes

whatsmyuri:  slaveOk
  {whatsmyuri:1}

7.1 数据库命令工作原理

数据库命令总会返回一个包含“ok”键的文档。表示命令执行成功或者失败。如果失败,则返回文档会包含另外一个键”errmsg”描述命令失败的原因。如果试着删除已经删除的集合“collection”

> db.runCommand("drop", "collection");
2018-11-17T09:31:55.111+0800 E QUERY    [thread1] Error: Second argument to DB.runCommand(drop) must be an object: (type: string): "collection" :
DB.prototype._mergeCommandOptions@src/mongo/shell/db.js:105:1
DB.prototype.runCommand@src/mongo/shell/db.js:153:25
@(shell):1:1
> db.runCommand({"drop", "collection"})
2018-11-17T09:32:20.231+0800 E QUERY    [thread1] SyntaxError: missing : after property id @(shell):1:21
> db.runCommand({"drop": "collection"})
{
        "ok" : 0,
        "errmsg" : "ns not found",
        "code" : 26,
        "codeName" : "NamespaceNotFound"
}
>

MongoDB中的命令被实现为一种特殊类型的查询,这些特殊的查询会在$cmd集合上查询。runCommand只是接受一个命令文档,并且执行与这个命令文档等价的查询。所以drop命令会被转化为如下代码:

db.$cmd.findOne({“drop”, “collection”})

当MongoDB服务器得到一个在$cmd上的查询时,不会对这个查询进行通常的查询处理,而是会使用特殊的逻辑对其进行处理。几乎所有的MongoDB驱动程序都会提供一个类似runCommand的辅助函数,用于执行命令,而且命令会以比较简单的方式执行。

8 总结

文档主要阐述非关系型数据库Mongo的查询,详细阐述了数据库连接,查询条件以及许多操作符的使用,阐明了查询数组时的注意细节。在讲述游标内容时对于limit、sort和skip方法进行了阐述和演示,最后对于数据库命令的执行原来进行简单的阐述。通过此文档可以了解mongoDB的简单的查询并能实际运用于自己的工作和生活中,对于程序开发人很有必有。通过对mongoDB shell的掌握能够很快帮助我们熟悉mongoDB的使用,以及代码的开发。

9 文档下载

https://download.csdn.net/download/lk142500/10790209

  • 12
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值