整理mongodb文档:find方法查询数据 求关注,求批评,求指出,如果哪儿不清晰,请指出来,谢谢
文章概叙
如题,本文讲的是如何用find查询数据,如何在数组、字段、对象中查询,以及‘或’等查询操作,最后讲了一些参数。依旧是在shell下操作。
数据准备
查询数据是db操作中很重要的一步,而mongodb又是Nosql的代表。所以,准备了两条数据,分别是有string,array,number,object的,方便后面的操作以及讲解。
[{
"string": "str1",
"num": 1,
"obj": { 'name1': 'value1' },
"arr": ["arr11", 'arr12']
},
{
"string": "str2",
"num": 2,
"obj": { 'name2': 'value2' },
"arr": ["arr21", 'arr22']
}]
find
Selects documents in a collection or view and returns a cursor to the
selected documents.
大概意思就是选择集合或视图中的文档,并将光标返回到所选文档。
首先来个最简单的用法,直接使用find方法查询出所有的数据,让大家有个直观的了解
db.test.find()
数据查询成功,但是这样子我们查询出来的是整个表的数据,实际开发中很少这样子做。毕竟一个表几个亿的数据是很正常的,而我们再看下文档中关于find方法的描述
看出来,有两个参数,第一个是我们的查询条件,第二个是我们的返回字段操作
字段查询
假定一个例子,我们只需要查询出num为1的数据,那么我们可以这样子
db.test
.find({ num: 1 })
这样子,我们就查询出了我们想要的那条数据,而如果存在多条数据的num都为1,我们可以再增加一些查询的条件,如下:
db.test.find({
num: 1,
string: 'str1'
})
这样子的意思,就是查询string为str1,并且num为1的数据。相当于我们的‘并’查询,既然有‘并’查询,那么就有‘或’查询,假设我们要查询num为1或则2的数据,我们的查询条件可以这么写:
db.test.find({
"$or": [{ num: 1 }, { num: 2 }]
})
db.test.find({
num: { "$in": [1, 2] }
})
根据字面意思,第一个sql的意思是一个‘或’操作,其中满足num为1或则2的时候,而第二个sql的意思则是如果num这个字段是在我们的1,2这两个之间的时候返回,两者实现的效果是一样的,但是可以看到or的操作是先把操作符放在外层,然后再将可能的条件列举出来,而in的操作是具体对某个字段的操作。这两个的用法需要注意下。
讲述完了"$or"的用法,接下里再讲解下如果必须加入其他条件以及正则的使用,正则的使用很重要,在我们做sql查询的时候,我们要匹配数据经常用到。
举个例子,现在我们还需要string字段为‘1’结尾的,sql应该如下:
db.test.find({
string:/1$/,
"$or": [{ num: 1 }, { num: 2 }]
})
有正则经验的朋友可以理解出,/1$/是正则的写法,意思就是1结尾,上述的sql是满足string以1结尾,且存在num为1或则num为2的情况。
讲解完了’in’这两个比较重要的,还有正则的,剩下的是’gt’等用法,这个建议大家自己按照我的例子去敲一下。官网有很明确的文档讲到这几个的作用,当然,不大明确的,可以在下面跟我留言。我给个链接(最主要希望大家自己学习怎么查找文档)。
对象查询
字段的查询是最简单的,基本只要用键值对的形式查询就可以,但对于新手来说,对象查询肯定会一脸懵逼,下面就用一个sql讲解如何使用对象查询
db.test.find({
"obj.name1": "value1"
})
可以看到,与上面的字段查询相比,我们将原来的‘string’变成了’obj.name1’,然后就查出了obj中name为value1的那条数据,看…多简单。
数组查询
本质上来说,对象跟数组是没有区别的,因为数组也是对象的一种,一种key为数字,但是被我们"忽略"掉的key,所以我们使用也可以使用
db.test.find({
"arr.0": "arr1"
})
这样子看起来很奇怪,但是能不能查询出我们刚刚那条数据呢?很明显,是可以的
但是我们实际开发中怎么保证数组的第一个数据(key为0的那条)是arr11呢?所以我们一般会用下面的方法去查询
db.test.find({
"arr": "arr11"
})
没啥好解说的,非要理解,就是遍历,查看每一条的arr字段,看看是不是数组类型,是的话就看看有没有arr11这个值这样子。
字段筛选
讲解完了查询的条件,就轮到了字段的筛选了,举一个例子,我们只需要返回string这个字段,那么我们可以用下面的sql
db.test.find(
{ string: "str1" },
{ string: 1 }
)
第一个参数我们之前讲过了,也就是查询的条件,这儿的意思是只要string的值为str1的数据。
第二个参数的意思是返回string参数,其中有两个值,分别是1和0。1代表的是要返回,0代表的是不要返回。
这儿可以看到,虽然没有设置,但是还是返回了_id,毕竟人家是唯一id,比较牛逼,所以有点特权很正常。那么按照上述所说的,我们不想要返回_id,可以设置下面这样子
db.test.find(
{ string: "str1" },
{ string: 1, "_id": 0 }
)
但是呢,部分朋友应该知道一条规则,就是0跟1是不能同时出现的,不然会出现很奇怪的情况,比如(我这儿是在很正经的科普mongodb,请不要想歪)
db.test.find(
{ string: "str1" },
{
"obj": 1,
string:0
}
)
意思就是你不能在进来的时候还出去。
除此之外,我们也可以使用下面这种情况
db.test.find({},
{
"obj.name1": 1,
}
)
意思就是我只要返回obj对象的name1,这么做原因也很简单,部分人会将头像之类图片转化为base64,然后将字符串插入到db中,导致返回的数据过多的时候卡死,而这样做就可以让我们只拿到想要的数据。
collation
讲解完了mongodb的find方法,大家可能发现,我之前一直讲的参数collation在这儿好像没有了,但是collation的重要性又不言而喻,所以mongodb更不可能放弃它,尤其是在find这种最需要它的api中。所以这儿提一嘴如何使用collaion。
db.test
.find()
.collation({ locale: 'simple' })
cursor
对于游标,我不大想介绍(我后面可能会写一个关于游标这个设计的博客,本文主要设计的是查询数据,我不想超过十分钟)。
大概理解为它是一个指针,就像是linux的软连接、c的指针,当我们拿到它的时候,它只是一串地址,指向那条我们想要的数据,当我们真正想要操作数据的时候,它会带我们去到那个文件的地方,是一个很棒的设计。
请记住一点,我们的数据都是在shell中找到的,所以我们返回的都是一个一个游标,具体请看上面所说的
Selects documents in a collection or view and returns a cursor to the
selected documents.
所以我们在代码中需要加一个toJSON或是toArray来将其转化,不过,我们更多是使用lean方法。
好消息是lean() 方法可以帮助我们获得更快的数据获取速度,因为它能够将 MongoDB 查询结果直接转化为 JavaScript 对象(或 JSON 字符串)而不需要创建 Mongoose 模型实例。
坏消息是lean只能在find方法中使用。
db.test
.find()
.lean()
最后的啰嗦
增删改查,没有一个是不重要的,相对于聚合,索引,集群这些,对于新手增删改查是最重要的。希望大家能好好敲一遍代码或者看下项目里的代码!