MongoDB基础之查询文档

1 查询操作

1.1 定义

MongoDB 查询文档使用 find() 方法
find() 方法以非结构化的方式来显示所有文档。

MongoDB 查询数据的语法格式如下:

db.collection.find(query, projection)

相关参数:

  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)
    若不指定 projection,则默认返回所有键,指定 projection 格式如下(0:不显示,1:显示),有两种模式,但是两种模式不可混用
    • db.collection.find(query, {title: 1, by: 1}) inclusion模式 指定返回的键,不返回其他键
    • db.collection.find(query, {title: 0, by: 0}) exclusion模式 指定不返回的键,返回其他键
      比如:_id 键默认返回,需要主动指定 _id:0 才会隐藏

1.2 查询操作

1.2.1 基础查询

1.2.1.1 pretty

如果需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:

>db.col.find().pretty()

pretty() 方法以格式化的方式来显示所有文档。

除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。

1.2.1.2 求总数

count()函数主要求总数

求集合中总数
db.col.count();
求过滤后的总数
db.col.find().count();

注意
在和分页联合使用时需要注意:

count()函数是假即:0或空,则查询出来是总数量
db.goods.find().count(); // 31
db.goods.find().skip(2).limit(3).count();  //31
db.goods.find().skip(2).limit(3).count(0);  //31

count(1)函数是假即:1,则查询出来是实际数量
db.goods.find().skip(2).limit(3).count(1);  //3

1.2.2 查询表达式

MongoDB查询表达式说明

查询表达式对应SQL表达式示例说明描述备注
$gt>{field:{$gt:value}}查询大于某条件的值
$gte>={field:{$gte:value}}查询大于或等于某条件的值
$lt<{field:{$lt:value}}查询小于某条件的值
$lte<={field:{$lte:value}}查询小于或等于某条件的值
$eq={field:{$eq:value}}查filed列的值 等于 value 的文档也可以直接用冒号:表示等于
$ne!={field:{$ne:value}}查filed列的值 不等于 value 的文档
$inindb.book.find({like:{$in:[10,11,20]}});查询在集合中的值
$ninnot indb.book.find({like:{$nin:[10,11,20]}});查询不在集合中
$all无对应项,指数组所有单元匹配{field:{$all:[v1,v2..]}} 取出 field列是一个数组,且至少包含 v1,v2值
$slice无对应项,限制数组元素的个数$slice:[a,b]a是正数时,起始位置是a+1,a是负数时,起始位置a(倒数数组),b是输出个数
$oror{$or:[{filed1:value1,filed2:value2}]}查询出满足fileld1或者field2条件的文档
$andand{$and:[{filed1:value1,filed2:value2}]}查询出既有field1又有field2字段的文档还可以用逗号表示and,每个键(key)以逗号隔开,即常规 SQL 的 AND 条件
$notnotdb.book.find({like:{$not:{$in:[10]}}});not可以和其他连用这里是和in连用,表示不在集合中的文档
$nor无对应项,指所有列举条件都不应成功为真{$nor:[条件1,条件2]}所有条件都不满足的文档为真返回
$exists无对应项,某列存在则为真{field:{$exists:1}}查询出含有field字段的文档
$mod无对应项,满足某求余则为真db.book.find({field:{$mod:[3,2]}});查询出含有field字段除数为3余数为2的文档,即:field%3==2
$type无对应项,满足某类型则为真{field:{$exists:1}}查询出含有field字段的文档
$wherewheredb.goods.find({$where:'this.cat_id != 3 && this.cat_id != 11'});可以写成类似于SQL的语法$where查询时, mongodb是把bson结构的二进制数据转换为json结构的对象,然后比较对象的属性是否满足表达式.速度较慢
$regex正则表达式匹配则为真db.posts.find({tags:{$regex:"jav"}})正则表达式效率和$where一样也不是很高

$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
MongoDB中可以使用的类型如下表所示:

类型数字备注
Double1
String2
Object3
Array4
Binary data5
Undefined6已废弃。
Object id7
Boolean8
Date9
Null10
Regular Expression11
JavaScript13
Symbol14
JavaScript (with scope)15
32-bit integer16
Timestamp17
64-bit integer18
Min key255Query with -1.
Max key127

如果想获取 合中 为 String 的数据,可以使用以下命令:

db.col.find({"title" : {$type : 2}})'string'必须以字符串形式
db.col.find({"title" : {$type : 'string'}})

1.2.3 分页排序

1.2.3.1 分页limit

如果需要在MongoDB中读取指定数量的数据记录,可以使用MongoDBLimit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。

limit()方法基本语法如下所示:

>db.COLLECTION_NAME.find().limit(NUMBER)

注意:如果没有指定limit()方法中的参数则显示集合中的所有数据。

1.2.3.2 分页skip

我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。

skip() 方法脚本语法格式如下:

>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

以下实例只会显示第二条文档数据

>db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }

注意skip()方法默认参数为 0 。

limit(n).skip(n)连用相当于关系型数据库中的分页操作
limit(n) 是用来规定显示的条数,而skip(n) 是用来在符合条件的记录中从第一个记录跳过的条数,这两个函数可以交换使用。
比如:find({},{age:1,_id:0}).limit(2).skip(1),在符合条件的文档中,要显示两条文档,显示的位置从跳过第一条记录开始

但是skiplimit方法只适合小数据量分页,如果是百万级效率就会非常低,因为skip方法是一条条数据数过去的,建议使用where_limit过滤处理
这里我们假设查询第100001条数据,这条数据的Amount值是:2399927,我们来写两条语句分别如下:

b.test.sort({"amount":1}).skip(100000).limit(10)  耗时183ms
db.test.find({amount:{$gt:2399927}}).sort({"amount":1}).limit(10)  耗时53ms
1.2.3.3 排序sort

MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1-1 来指定排序的方式

  • 1 升序排列
  • -1是用于降序排列

sort()方法基本语法如下所示:

>db.COLLECTION_NAME.find().sort({KEY:1})

注意:当skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的limit()

1.2.4 正则表达式

MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。
MongoDB使用PCRE (Perl Compatible Regular Expression) 作为正则表达式语言

我们使用正则表达式不需要做任何配置。

准备文档,该文档包含了文章内容和标签:

{
   "post_text": "enjoy the mongodb articles on java",
   "tags": [
      "mongodb",
      "java"
   ]
}
1.2.4.1 使用正则表达式

以下命令使用正则表达式查找包含 java字符串的文章:

db.posts.find({post_text:{$regex:"java"}})

以上查询也可以写为/ /,这是JavaScript中正则写法:

db.posts.find({post_text:/java/})
1.2.4.2 不区分大小写的正则表达式

如果检索需要不区分大小写,我们可以设置 $options$i
以下命令将查找不区分大小写的字符串 java:

>db.posts.find({post_text:{$regex:"java",$options:"$i"}})

集合中会返回所有包含字符串 java的数据,且不区分大小写:

{
   "_id" : ObjectId("53493d37d852429c10000004"),
   "post_text" : "hey! this is my post on  java", 
   "tags" : [ "java" ]
} 
1.2.4.3 数组元素使用正则表达式

还可以在数组字段中使用正则表达式来查找内容。 这在标签的实现上非常有用,如果需要查找包含以 ja 开头的标签数据(va 或 jav或 java), 可以使用以下代码:

db.posts.find({tags:{$regex:"jav"}})
1.2.4.4 优化正则表达式查询

如果文档中字段设置了索引,那么使用索引相比于正则表达式匹配查找所有的数据查询速度更快。
如果正则表达式是前缀表达式,所有匹配的数据将以指定的前缀字符串为开始。例如: 如果正则表达式为 ^tut ,查询语句将查找以 tut 为开头的字符串。
这里面使用正则表达式需要注意:
正则表达式中使用变量。一定要使用eval将组合的字符串进行转换,不能直接将字符串拼接后传入给表达式。否则没有报错信息,只是结果为空!实例如下:

var name=eval("/" + 变量值key +"/i"); 

以下是模糊查询包含title关键词, 且不区分大小写:

title:eval("/"+title+"/i")    
等同于 title:{$regex:title,$Option:"$i"}   

1.3 游标

1.3.1 定义

通俗的说,游标不是查询结果,而是查询的返回资源,或者接口,通过这个接口,可以逐条读取

1.3.2 游标声明

var cursor =  db.collectioName.find(query,projection);
cursor.hasNext(); 判断游标是否已经取到尽头
cursor. Next(); 取出游标的下1个单元

用while来循环游标

> var mycursor = db.bar.find({_id:{$lte:5}})
> while(mycursor.hasNext()) {
... printjson(mycursor.next());
... }

用for循环

// 声明游标
var cursor = db.goods.find();
// 循环游标
for(var doc=true;cursor.hasNext();) { printjson(cursor.next());}

也可以简写:
for(var  cursor=db.goods.find(), doc=true;cursor.hasNext();) { printjson(cursor.next());}

1.3.3 操作游标

游标还有一个迭代函数,允许我们自定义回调函数来逐个处理每个单元.
cursor.forEach(回调函数);

var gettitle = function(obj) {print(obj.goods_name)}
var cursor = db.goods.find();
cursor.forEach(gettitle);

通过cursor一次性得到所有数据, 并返回数组.

var cursor = db.goods.find();
printjson(cursor.toArray());  //看到所有行
printjson(cursor.toArray()[2]);  //看到第2行

注意:不要随意使用toArray(),原因: 会把所有的行立即以对象形式组织在内存里.可以在取出少数几行时,用此功能

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mongo是一种开源的、面向文档的NoSQL数据库管理系统。它使用类似于JSON的BSON(Binary JSON)格式来存储数据,具有高度灵活性和可伸缩性。 以下是一些MongoDB基础知识: 1. 文档和集合:MongoDB中的数据以BSON文档的形式进行存储。一组相关文档被组织在一个集合中,类似于关系数据库中的表。 2. 数据模型:MongoDB是面向文档的数据库,不需要事先定义表结构。每个文档可以有不同的字段,这使得数据模型非常灵活。 3. 主键:每个文档都必须有一个唯一的主键,称为"_id"字段。如果没有显式指定主键值,MongoDB会自动生成一个唯一的ObjectId。 4. 查询语言:MongoDB使用查询语言来从集合中检索数据。可以使用丰富的查询操作符和条件来过滤和排序结果。 5. 索引:为了提高查询性能,可以在集合中创建索引。索引可以根据指定的字段或字段组合快速定位数据。 6. 副本集:MongoDB支持副本集,通过复制数据到多个服务器实例来提供高可用性和容错性。 7. 分片:MongoDB可以通过分片来实现横向扩展。数据根据指定的分片键自动分布到多个服务器上,以实现负载均衡和扩展性。 8. 数据操作:MongoDB提供了丰富的数据操作功能,包括插入、更新、删除、聚合等。 这些是MongoDB的一些基础知识,希望能对你有所帮助!如果你有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值