zoukankan      html  css  js  c++  java
  • mongoDB查询及游标

    find文档

    1.find简介

    使用find查询集合中符合条件的子集合

    1 db.test.blog.find();  

    类似于sql查询

    1 select * from test.blog 

    上面的查询是返回多有多有集合,并且是所有键。有时我们也会指定返回部分键,这样方式可以减少IO

    1 > db.test.blog.find({},{"age":1,"name":1});  
    2 { "_id" : 1, "age" : 1, "name" : "joe" }  
    3 { "_id" : ObjectId("533a1c27b653a97435a02030") }  
    4 { "_id" : "2" }  

    类似sql查询

    1 select age , name from test.blog  

    使用带条件的查询举例:

    1 > db.test.blog.find({"age":1});  
    2 { "_id" : 1, "age" : 1, "like" : [ "eat", "abc" ], "name" : "joe" }  

    类似sql查询

    1 select * from test.blog where age = 1  

    2.查询条件

    比较操作符:

    命令 描述
    $lt <
    $lte <=
    $gt >
    $gte >=
    1 > db.student.find({age:{$lte:12,$gte:10}}); 

    类似sql

    1 select * from student where age >= 10 and age <= 12 

    $ne:不等,能用于多有类型的数据

    1 > db.student.find({age:{$ne:10}});  

    类似sql

    1 select * from student where age != 10

    3.OR查询

    命令 描述
    $in 查询一个键的多个值
    $or 用来完成多个键值的任意给定值

    $in用法代码

    1 > db.student.find({age:{$in:[10,13]}});  
    2 { "_id" : 0, "name" : "aa0", "age" : 10 }  
    3 { "_id" : 3, "name" : "aa3", "age" : 13 }  
    4 { "_id" : 5, "name" : "aa5", "age" : 10 }  
    5 { "_id" : 8, "name" : "aa8", "age" : 13 }  

     类比sql

    1 select * from student where age in (10,13);

    $or代码

    1 > db.student.find({"$or":[{"age":{$in:[10,13]}},{"name":"aa7"}]});  
    2 { "_id" : 0, "name" : "aa0", "age" : 10 }  
    3 { "_id" : 3, "name" : "aa3", "age" : 13 }  
    4 { "_id" : 5, "name" : "aa5", "age" : 10 }  
    5 { "_id" : 7, "name" : "aa7", "age" : 12 }  
    6 { "_id" : 8, "name" : "aa8", "age" : 13 }  

    类比sql

    1 select * from student where age in (10,13) or name = 'aa0'  

    4.$not

    $not是原条件句,可以用在任何其他条件之上

    1 > db.student.find({"age":{$not:{"$mod":[5,1]}}});  
    2 { "_id" : 0, "name" : "aa0", "age" : 10 }  
    3 { "_id" : 2, "name" : "aa2", "age" : 12 }  
    4 { "_id" : 3, "name" : "aa3", "age" : 13 }  
    5 { "_id" : 4, "name" : "aa4", "age" : 14 }  
    6 { "_id" : 5, "name" : "aa5", "age" : 10 }  
    7 { "_id" : 7, "name" : "aa7", "age" : 12 }  
    8 { "_id" : 8, "name" : "aa8", "age" : 13 }  
    9 { "_id" : 9, "name" : "aa9", "age" : 14 }  

    $mod:将查询的值除以第一个参数“5”,如果余数等于第二个参数“1”那么返回该值

    5.null

    null可以匹配自身(key对应的值为null),还可以匹配“不存在的”(文档中不存在这个key)。

     1 > db.student.find({"like":null});  
     2 { "_id" : 1, "name" : "aa1", "age" : 11 }  
     3 { "_id" : 2, "name" : "aa2", "age" : 12 }  
     4 { "_id" : 3, "name" : "aa3", "age" : 13 }  
     5 { "_id" : 4, "name" : "aa4", "age" : 14 }  
     6 { "_id" : 5, "name" : "aa5", "age" : 10 }  
     7 { "_id" : 6, "name" : "aa6", "age" : 11 }  
     8 { "_id" : 7, "name" : "aa7", "age" : 12 }  
     9 { "_id" : 8, "name" : "aa8", "age" : 13 }  
    10 { "_id" : 9, "name" : "aa9", "age" : 14 }  
    11 { "_id" : 0, "age" : 10, "like" : null, "name" : "aa0" }  
    12   
    13 > db.student.find({"like":null,"like":{$exists:true}});  
    14 { "_id" : 0, "age" : 10, "like" : null, "name" : "aa0" } 

    说明:$exists:判断键是否存在

    6.正则表达式

     1 > db.student.find({"name":/aa/});  
     2 { "_id" : 1, "name" : "aa1", "age" : 11 }  
     3 { "_id" : 2, "name" : "aa2", "age" : 12 }  
     4 { "_id" : 3, "name" : "aa3", "age" : 13 }  
     5 { "_id" : 4, "name" : "aa4", "age" : 14 }  
     6 { "_id" : 5, "name" : "aa5", "age" : 10 }  
     7 { "_id" : 6, "name" : "aa6", "age" : 11 }  
     8 { "_id" : 7, "name" : "aa7", "age" : 12 }  
     9 { "_id" : 8, "name" : "aa8", "age" : 13 }  
    10 { "_id" : 9, "name" : "aa9", "age" : 14 }  
    11 { "_id" : 0, "age" : 10, "like" : null, "name" : "aa0" }  
    12 > db.student.find({"name":/aa1/});  
    13 { "_id" : 1, "name" : "aa1", "age" : 11 } 

    使用/reg/来表示正则

    7.查询数组

    命令 描述
    $all 匹配数组中的多个元素
    $size 匹配数组的长度
    $slice 返回数组中的子集合

    $all代码

    1 > db.food.find({"fruit":{$all:["apple","banana"]}});  
    2 { "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }  
    3 { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }  
    4   
    5 > db.food.find({"fruit":"apple"});  
    6 { "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }  
    7 { "_id" : 2, "fruit" : [ "apple", "kumquat", "orange" ] }  
    8 { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }  

    $size代码

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

    8.查询内嵌文档

    用“.”表示法是查询文档区别于其他文档的主要特点。查询文档可以包含点,来表示深入内嵌文档内部。点表示法也是待插入的文档不能包含"."的原因。

    1 > db.food.insert({"_id":4,"fruit":{"apple":"good","banana":"good"}});  
    2 > db.food.insert({"_id":5,"fruit":{"apple":"best","banana":"good"}});  
    3 > db.food.find({"fruit.apple":"good"});  
    4 { "_id" : 4, "fruit" : { "apple" : "good", "banana" : "good" } }  
    5 > db.food.find({"fruit.apple":"best"});  
    6 { "_id" : 5, "fruit" : { "apple" : "best", "banana" : "good" } } 

    9.$where

    如果前面的查询方法都不能实现,那么就轮到$where子句了,用它可以执行任意javascript作为查询的一部分,where可以接受一个javascript函数作为查询条件,并且迭代当前集合里面的所有文档,如果满足函数条件,则返回这个文档。最典型的就是比较文档中的两个键的值是否相等。

    1 //现在有下面这个集合,要找出库存和销量相同的记录  
    2 > db.foo.insert({"name":"apple","ku_cun":100,"xiao_liang":100});  
    3 > db.foo.insert({"name":"banana","ku_cun":120,"xiao_liang":100});  
    4   
    5 //下面是用$where查询  
    6 > db.foo.find({$where:function(){if(this.ku_cun == this.xiao_liang)return true;}  
    7 });  
    8 { "_id" : ObjectId("533bd36909fa3b030490f059"), "name" : "apple", "ku_cun" : 100  
    9 , "xiao_liang" : 100 }  

    this就是引用当前集合中的一个文档。

     $where除了可以接受一个function函数,还可以接受一个function的字符串

    1 //这是接受一个function的字符串,效果是一样的  
    2 > db.foo.find({$where:"function(){if(this.ku_cun == this.xiao_liang)return true;  
    3 }"});  
    4 { "_id" : ObjectId("533bd36909fa3b030490f059"), "name" : "apple", "ku_cun" : 100  
    5 , "xiao_liang" : 100 }  

     如果return true;表示当前遍历的这个文档满足条件,那么就把这条记录(文档)返回出来。

    还有更复杂的查询可以利用MapReduce

    特别说明:使用$where效率比较低,因为mongodb要将BOSN数据转成javascript数据,然后一个一个遍历操作。并且不能使用索引。建议使用常规查询作为前置过滤,然后与$where组合使用。

    2.游标

    数据库使用游标来返回find的执行结果。客户端对游标的实现通常能够对最终结果进行有效的控制。可以限制结果的数量(limit),掠过部分数据(skip),对结果进行排序(sort),或者执行其他操作.

    Skip_limit_sort代码

     1 //使用limit,获取查询结果的前5条记录(文档)  
     2 > db.student.find().limit(5);  
     3 { "_id" : 1, "name" : "aa1", "age" : 11 }  
     4 { "_id" : 2, "name" : "aa2", "age" : 12 }  
     5 { "_id" : 3, "name" : "aa3", "age" : 13 }  
     6 { "_id" : 4, "name" : "aa4", "age" : 14 }  
     7 { "_id" : 5, "name" : "aa5", "age" : 10 }  
     8   
     9 //使用skip和limit,跳过查询结果的前两条,取得后面的5条记录(文档)  
    10 > db.student.find().skip(2).limit(5);  
    11 { "_id" : 3, "name" : "aa3", "age" : 13 }  
    12 { "_id" : 4, "name" : "aa4", "age" : 14 }  
    13 { "_id" : 5, "name" : "aa5", "age" : 10 }  
    14 { "_id" : 6, "name" : "aa6", "age" : 11 }  
    15 { "_id" : 7, "name" : "aa7", "age" : 12 }  
    16   
    17 //使用sort,对跳过前2条之后的5条记录按照age倒序  排序  
    18 > db.student.find().skip(2).limit(5).sort({"age":-1});  
    19 { "_id" : 3, "name" : "aa3", "age" : 13 }  
    20 { "_id" : 8, "name" : "aa8", "age" : 13 }  
    21 { "_id" : 2, "name" : "aa2", "age" : 12 }  
    22 { "_id" : 7, "name" : "aa7", "age" : 12 }  
    23 { "_id" : 1, "name" : "aa1", "age" : 11 }  
    24   
    25 //使用sort,对跳过前2条之后的5条记录按照age顺序  排序  
    26 > db.student.find().skip(2).limit(5).sort({"age":1});  
    27 { "_id" : 1, "name" : "aa1", "age" : 11 }  
    28 { "_id" : 6, "name" : "aa6", "age" : 11 }  
    29 { "_id" : 2, "name" : "aa2", "age" : 12 }  
    30 { "_id" : 7, "name" : "aa7", "age" : 12 }  
    31 { "_id" : 3, "name" : "aa3", "age" : 13 }  

     因为mongodb相同的键可以对应不用类型,所以在排序时有可能存在不同类型的比较。mongodb有一个预先定义好的,从小到大:

     1 最小值
     2 null
     3 数字
     4 字符串
     5 对象/文档
     6 数组
     7 二进制数据
     8 对象ID
     9 布尔型 
    10 日期型
    11 时间戳
    12 正则表达式
    13 最大值

    如果skip过多的文档,会导致速度比较慢,这是你的分页可能的想想其他方法了。例如可以根据时间排序,然后下一页时,根据上一页的最后一条记录的时间作为这一页查询的条件。

    当神已无能为力,那便是魔渡众生
  • 相关阅读:
    java后端解决请求跨域
    在IDEA中找不到Mapper报错
    ES6拼接数组与小程序本地存储
    小程序云开发实现微信发说说
    SQLServer的操作以及一些概念
    数据依赖(决定),码,范式,规范化与反规范化
    Git的使用上传与下载github
    JS中Map和ForEach的区别
    进入React的世界
    Node的重要性
  • 原文地址:https://www.cnblogs.com/liuzhongfeng/p/5588680.html
Copyright © 2011-2022 走看看