MongoDB的用法集锦:查询篇----->持续更新中

MongoDB的用法集锦:查询篇----->持续更新中

实验环境: mongodb3.2


使用mongodb可以使用k-v演算的含义对以前的关系SQL进行改写

但是也有一些陷阱,并不是照猫画虎就可以的。

因为mongodb是非关系型数据库,一些关系性的东西需要我们靠逻辑进行维护

使用sql,首先要会这个CRUD操作

记住mongodb中基本的存在是文档,所以条件呀,值什么的都要以文档的形式表现出来

1--查询

1.1常用的条件语义操作符

记忆要点: 条件限制是条件语义,大部分操作符是处于表语位置,所以大部分操作符是在属性名字的后面

                      但是也有一些是在前面的,主要是他们后面的值都是数组。

                       有一部分的操作符的值是开关,也就是true和false,但是书上写的是1或者0,其实使用true和false更好一点

                      数组的是特殊的文档,可以使用条件定位和位置定位

a:  常见的条件操作符

     $gt,$lt,$gte,$lte,$ne,$all,$exists,$mod,$in,$nin,$nor,$or,$and,$size,$sort,$each,$slice,$where

b: 操作符在前面的,他们的值是数组

    $and ,$or,$nor

     $and:[{//条件文档1},{//条件文档2},{//条件文档3}...]

     $or:[{//条件文档1},{//条件文档2},{//条件文档3}...]

    $nor:[{//条件文档1},{//条件文档2},{//条件文档3}...]


  另外值是数组的还有这个  $each和$mod,但是他们是属性后面的存在

  $skill:{$each:['java','c++']}

  $num:{$mod:[2,0]}   //num%2==0

c: and 的语义使用,即可,但是也可以使用$and 进行描述

     $and:[{a:{$lt:8}},{b:{$gt:5}}]


d:一切的条件都可以使用$where来进行描述

       $where:function(){

           return this.xxxx的条件表达式

           //this就是当前的文档

         }

使用例子:

    1:等于语义 select * from test.person where name = 'fengk'

    >use test

    >db.person.find({name:'fengk'})

    >db.person.find({name:{$in:['fengk']}});

    >db.person.find({$where:function(){

          return this.name=='fengk';

      }})

    2:且的语义 select * from test.person where index >3 and index<=8

    >db.person.find({index:{$gt:3,$lte:8}})

    >db.person.find({$and:[{index:{$gt:3}},{index:{$lte:8}}]})

    >db.person.find({$where:function(){

          return this.index >3 && this.index<=8

      }})

     错误的用法

      从上面可以看到这个,在文档中是有且的概念的,因此使用,来分隔就是且的语义

      但是这个只能适用于不同的key,同一个key使用的时候只能写一个key,不能重复

      例如:

      >db.person.find({index:{$gt:3},index:{$lte:8}})

      这种写法将这个index出现多次的时候,最后的结果只是最后的  index:{$lte:8}起的限制作用

     这个时候只能把key写成一个

     例如描述这个  select * from test.person where index =4 and index <7

      等于的语义本身是: 进行解释的,但是处于复合条件中的等于,由于key不能重复只能使用这个 $in来进行描述了

      >db.person.find({index:{$in:[4],$lt:7}})

     可以使用$and 但是它是不被优化的,所以效率上不能保证。

    3:且的语义   select * from test.person where index <7 and kind='B'

         >db.person.find({index:{$lt:7},kind:'B'})

     4:in的语义  select * from test.person where index in(3,5,8)

       >db.person.find({index:{$in:[3,5,8]}})

     5:  or的语义  select * from test.person where index =2 or kind = 'C'

        >db.person.find({$or:[{index:2},{kind:'C'}]})

     6:限制输出列表  select index,kind from test.person where kind !='C'

        >db.person.find({kind:{$ne:'C'}},{index:1,kind:1,_id:0})

      注意只要把这个输出的列表项设为1就可以了,但是有一个例外那就是这个_id ,所以把_id要设为0

       前面说过这个1和0是开关的时候使用true和false更为贴切,这样不用和其他的值弄混

       用true和false来写更为合适

      >db.person.find({kind:{$ne:'C'}},{index:true,kind:true,_id:false})


    7:null查找  select * from test.person where info is null

         >db.person.find({info:null})         

         上面的写法是逻辑不完善的,因为这个info属性不存在的文档也是符合这个条件的。

         所以还要加上这个存在的限制条件

       >db.person.find({info:{$in:[null],$exists:true}})


      8:容易出错的元操作符  $not

          这个操作符是可以作用与其他的条件操作上面的,但是要注意它只是条件表达式中可以限制

          比如  $lt  ,$mod,$ne  等等

          对于$and ,$or ,$nor这种处于前面的操作符不能给他么限制

       例如  $not:{$and:[....]}  这种写法是错误的。

       $not也只能和其他一般的语义操作符一样位于属性的后面


      >db.person.find({kind:{$not:{$ne:'A'}}})

1.2数组的查询

a:  条件操作符

数组的值  可以看成是特殊的k:V结构

 也就是一个key有多个值的情况

  {kind:['A','B','C']}

可以理解成这个多值的情形

  {kind:'A','B','C'}

这样以来对于数组的查询和一般的条件的语义查询没有其他的区别

>db.person.find({kind:'B'})

你看这种写法和一般的没有区别吧。    

 

但是反过来思考下:这种方便性也带来其他的困扰

给定条件   db.person.find({kind:'B'})

我们不能区分它到底是一个一般的条件,还是数组的条件

如果我们的条件逻辑不严密,那么数组中满足改条件的元素存在的话,数组也是可以被过滤出来

我们的逻辑此时就要考虑到数组的情况



b:  数组全部匹配

   >db.person.find({kind:['A','B','C']})


c:  数组子集匹配,使用  $all

     >db.person.find({kind:{$all:['B','C']}})

d:  长度匹配,使用$size,但是$size不能和$gt,$lt等结合使用

      >db.person.find({kind:{$size:3}})

e:  切片操作,$slice

    如果你接触过这个python就知道可迭代对象的切片思想了

    $slice:[offset,len]

    如果这个offset为0的时候也可以省略为  $slice:len

    也就是截取  [offset,offset+len)区间的元素角标指定的元素子集合

    其中这个len可以是负号

     +len表示从元素0开始截取

     -len表示从数组末尾反向截取


但是注意这个使用的时候它有些特殊。

如果按照一般的使用方法用会报 unknown operator: $slice

比如  > db.person.find({index:6,comments:{$slice:2}})

使用find的时候,它的第二个参数是要返回的键,也就是查询的列表项目

但是如果使用这个$slice的时候,它出现在第二个参数中,用于指定一个数组元素要返回一个子集数组

所以这个操作符必须出现再find的第二个参数中

>var obj = db.person.findOne({index:6})

>db.person.find(obj,{comments:{$slice:2}})

>db.person.find(obj,{comments:{$slice:-2}})

> db.person.find(obj,{comments:{$slice:[1,2]}})

1.3数据库命令

>db.person.find()

> db.runCommand({find:'person'})


1.4 排序分页


排序使用这个sort函数进行

sort({key:1})  按照key进行升序

sort({key:-1})  按照key进行降序

limit(num) 限定结果只有num个元素

skip(num) 略过前num个元素

count({条件文档})进行个数查询


>db.person.find().sort({index:1})

如果我们的数据条数是11条

>var count = db.person.count()

我们分页,一页的数据条数是3条

那么我们可以分页的页数:

> count%3==0?count/3:Math.floor(count/3)+1

4
第一页的数据:

> db.person.find().limit(3).skip(0)

第二页的数据

> db.person.find().limit(3).skip(3)

第三页的数据

> db.person.find().limit(3).skip(6)

第四页的数据

> db.person.find().limit(3).skip(9)


所以如果我们的页数是page,每页数据的条数是num

那么第k 页的查询是

>

第三页的数据

> db.person.find().limit(page).skip((k-1)*page)


1.5 分组

group函数,它接受一个文档作为参数

 有如下的属性:

key:表示按那些字段进行分组

        例如 key:{kind:1}   1表示这个分组中的key要显示出来

initial:表示初始化的值

        例如  initial:{person:[]}

$reduce: function(cur,prev)

如果接触过python就知道这个reduce函数了

它是一种合成的思想

用于操作复合的函数关系

把初始值给这个prev

然后将它和数组的第一项进行函数关系运算

得到的结果再和数组的第二项进行函数运算

如此下去。

condition:{条件过滤文档}

表示最后的分组中要过滤的条件

finalize:function(out)

表示分组完成之后每组必须进行的操作,这个out就是$reduce函数中的prev对象


这个group函数的操作就是先按照key进行分组

然后每一个分组都要按照  initial,conditon,$reduce,finalize来进行加工操作

最后输出的东西就是这个prev对象的属性和这个finalize函数中的out对象的属性


  > db.person.group({
... key:{kind:1},
... initial:{person:[]},
... condition:{index:{$mod:[2,0]}},
... $reduce:function(cur,prev){
... prev.person.push(cur.index);
... }
... ,
... finalize:function(out){
... out.count = out.person.length;
... }
... }
... )






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值