Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1538972
  • 博文数量: 1481
  • 博客积分: 26784
  • 博客等级: 上将
  • 技术积分: 17045
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-12 09:22
文章分类

全部博文(1481)

文章存档

2014年(10)

2013年(353)

2012年(700)

2011年(418)

分类: PHP

2013-07-04 16:09:24

HELLO,各位童鞋,我又上来唠叨啦,不知道昨天的内容大家能否消化呢?

我相信这点内容对大家都是小case,一定So easy,如果学习过程当中遇到什么问题,一定要给我反馈哦,我的微博,邮箱,BBS,个人博客,统统为大家开放!


好了,不多说了,我今天给大家唠叨点啥呢?

今天我来给大家带上MongoDB查询方法的详细讲解,内含各种案例,各种精彩,不容错过!

我们先来回顾下上文的内容,上文我给大家详细讲了下MongoDB的update方法以及常用的修改器,希望大家能够下来多加练习,巩固所学知识。

至此,我们对MongoDB的增、删、改方法都已经搞定,那么今天就来带大家学习MongoDB的查询方法,学完MongoDB的这个方法,我们就可以写一个BBS论坛了,怎么样,是不是很兴奋啊。

那我们开始,首先我们先来回顾下SQL语句当中的查询语法是什么样的?

SELECT 字段1,字段2[,字段3[,字段4]......... ] FROM 表名 [ WHERE 条件 ] [ ORDER BY 字段名 DESC|ASC ] [ LIMIT [记录偏移量,]显示的记录总数 ] 

在SQL语句当中我们使用SELECT语句,而在MongoDB当中,我们使用find和findOne方法:

find方法:

功能:查询集合中的文档

使用方法:db.user.find()

参数:

       第一个参数为要查询的条件

        第二个参数为要显示或不要显示的键名

我们来看一个例子:

现在我们来批量插入一组数据:

  1. > for(i = 1; i <= 20; i++){
  2. > ...db.user.insert(
  3.       {   "name": "李文凯"+i+"号",
  4.           "age":20+i,
  5.           "alias":"作业屠夫",
  6.           "girlfriend":[
  7.                    {"name":"凤姐","age":18},
  8.                    {"name":"芙蓉姐姐","age":19},
  9.                    {"name":"小月月","age":20}
  10.               ],
  11.            "hobby":["抽烟","喝酒","把妹"],
  12.            "baobiao":[
  13.                             {"name":"李强强","alias":"小而强大"},
  14.                             {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  15.                             {"name":"张涛","alias":"外纯内骚"}
  16.                      ]
  17.       }
  18. );
  19. > ...}
  20. >


因为MongoDB的shell客户端是JS引擎,所以在MongoDB的客户端下可以使用JS的语法,

因此插入命令执行后,集合中会出现20条新文档:

  1. {   "name": "李文凯1号",
  2.     "age":21,
  3.     "alias":"作业屠夫",
  4.     "girlfriend":[
  5.                 {"name":"凤姐","age":18},
  6.                 {"name":"芙蓉姐姐","age":19},
  7.                 {"name":"小月月","age":20}
  8.      ],
  9.      "hobby":["抽烟","喝酒","把妹"],
  10.      "baobiao":[
  11.                 {"name":"李强强","alias":"小而强大"},
  12.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  13.                 {"name":"张涛","alias":"外纯内骚"}
  14.      ]
  15. }
  16. <-------------------------------------------------------------------------------->
  17. {   "name": "李文凯2号",
  18.     "age":22,
  19.     "alias":"作业屠夫",
  20.     "girlfriend":[
  21.                 {"name":"凤姐","age":18},
  22.                 {"name":"芙蓉姐姐","age":19},
  23.                 {"name":"小月月","age":20}
  24.      ],
  25.      "hobby":["抽烟","喝酒","把妹"],
  26.      "baobiao":[
  27.                 {"name":"李强强","alias":"小而强大"},
  28.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  29.                 {"name":"张涛","alias":"外纯内骚"}
  30.      ]
  31. }
  32. <-------------------------------------------------------------------------------->
  33. {   "name": "李文凯3号",
  34.     "age":23,
  35.     "alias":"作业屠夫",
  36.     "girlfriend":[
  37.                 {"name":"凤姐","age":18},
  38.                 {"name":"芙蓉姐姐","age":19},
  39.                 {"name":"小月月","age":20}
  40.      ],
  41.      "hobby":["抽烟","喝酒","把妹"],
  42.      "baobiao":[
  43.                 {"name":"李强强","alias":"小而强大"},
  44.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  45.                 {"name":"张涛","alias":"外纯内骚"}
  46.      ]
  47. }
  48. <-------------------------------------------------------------------------------->
  49. {   "name": "李文凯4号",
  50.     "age":24,
  51.     "alias":"作业屠夫",
  52.     "girlfriend":[
  53.                 {"name":"凤姐","age":18},
  54.                 {"name":"芙蓉姐姐","age":19},
  55.                 {"name":"小月月","age":20}
  56.      ],
  57.      "hobby":["抽烟","喝酒","把妹"],
  58.      "baobiao":[
  59.                 {"name":"李强强","alias":"小而强大"},
  60.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  61.                 {"name":"张涛","alias":"外纯内骚"}
  62.      ]
  63. }
  64. <-------------------------------------------------------------------------------->
  65. {   "name": "李文凯5号",
  66.     "age":25,
  67.     "alias":"作业屠夫",
  68.     "girlfriend":[
  69.                 {"name":"凤姐","age":18},
  70.                 {"name":"芙蓉姐姐","age":19},
  71.                 {"name":"小月月","age":20}
  72.      ],
  73.      "hobby":["抽烟","喝酒","把妹"],
  74.      "baobiao":[
  75.                 {"name":"李强强","alias":"小而强大"},
  76.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  77.                 {"name":"张涛","alias":"外纯内骚"}
  78.      ]
  79. }      
  80. <-------------------------------------------------------------------------------->          
  81.                  /\
  82.                  ||
  83.                  ||
  84.                  ||
  85.                中间省略.....
  86.                  ||
  87.                  ||
  88.                  ||
  89.                  \/
  90. <-------------------------------------------------------------------------------->
  91. {   "name": "李文凯20号",
  92.     "age":40,
  93.     "alias":"作业屠夫",
  94.     "girlfriend":[
  95.                 {"name":"凤姐","age":18},
  96.                 {"name":"芙蓉姐姐","age":19},
  97.                 {"name":"小月月","age":20}
  98.      ],
  99.      "hobby":["抽烟","喝酒","把妹"],
  100.      "baobiao":[
  101.                 {"name":"李强强","alias":"小而强大"},
  102.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  103.                 {"name":"张涛","alias":"外纯内骚"}
  104.      ]
  105. }


好,如上所示,我们新插入了20条文档,

如果查询name为"李文凯1号"的文档,我们来这样做:

我们刚才讲了,find()方法的第一个参数为要查询的文档所要满足的条件,第二个参数为要显示的键名或者不要显示的键名,

那么好,我们就会使用find()方法了:

db.user.find({"name":"李文凯1号"},{"_id":0});

这就类似于我们的SQL语句:

SELECT name,age,alias,girlfriend,hobby,baobiao FROM user where name="李文凯1号"

这样就不会显示"_id"键,其他键都会显示。

说到这里,第二个参数是"key":0或者1,0代表不显示,1代表显示,如果加了"name":1,则除了"_id"和"name",其他键都不会显示,也就是说"_id"如果不设为0,则默认会显示

下面,我们把条件复杂化一些来看:

例如:

          我们要查询age大于30并且小于40的所有用户,find()方法应该怎么写?

SQL语句:

         SELECT * FROM user WHERE age>30

MongoDB语句:

        db.user.find({"age":{'$gt':30,'$lt':40}})

如上所示:

       ”大于“我们使用$gt

       ”小于“我们使用$lt

       同理,”大于等于“和”小于等于“我们分别使用”$gte“和”$lte“

       而”不等于“我们使用”$ne“

注意:在MongoDB当中,没有”$eq“,”等于“我们使用的是冒号":"

如果我们要满足name为”李文凯1号“或者name为”李文凯5号“的文档,要怎么做

在SQL语句中:

       SELECT * FROM user WHERE name="李文凯1号" or name=”李文凯5号“

       或者:

       SELECT * FROM user WHERE name in("李文凯1号","李文凯5号")

那在MongoDB当中:

       db.user.find({"name":{'$in':["李文凯1号","李文凯5号"]}})

如上所示,MongoDB当中的$in的功能与SQL语句当中的in的功能是一样的,语法结构为:

       "key":{$in:[值1,值2,值3,........]}

同样,$nin的语法结构与$in的语法结构完全相同,但意思完全相反。

又如:

        我们需要查询name为”李文凯1号“或者age为大于等于30的用户,要怎么做?

在SQL语句当中:

       SELECT * FROM user WHERE name="李文凯1号" or age>=30

在MongoDB当中,显然我们使用$in已经满足不了我们的需求,因此我们可以使用$or:

        db.user.find({'$or':[{"name":"李文凯1号"},{"age":{'$gte':30}}]})

这里的$or与SQL语句当中的or作用相同,

这里要注意:$or后面是两个不同的键,并且用数组的形式传递,数组的每一个元素是不同的键要满足的不同条件的对象,

因此$or语法结构为:

         '$or':[{"key1":条件},{"key2":条件},{"key3":条件}]

那么同样,我们可以使用$or来满足上例的需求:

        db.user.find({'$or':[{"name":"李文凯1号"},{"name":"李文凯5号"}]})

我们来总结一下:

$in和$nin主要针对同一键的值的或关系

$or主要针对不同键的值的或关系,同样可以针对同一键的值的或关系

接下来,我们再看,倘若我们要满足一下需求:

         我们要找出所有年龄为偶数的用户文档对象,该怎么做?

SQL语句中:

        SELECT * FROM user WHERE age%2=0

在MongoDB当中,我们可以使用$mod:

        db.user.find({"age":{'$mod':[2,0]}})

取奇数可以这样:

        db.user.find({"age":{'$mod':[2,1]}})

        或者:

        db.user.find({"age":{'$not':{'$mod':[2,0]}}})

由此可见,MongoDB中的$not是取反的意思,也就是偶数取反,即为奇数。

下面,如果我们插入一条新文档:

  1. {   "name": "李文凯21号",
  2.     "age":41,
  3.     "alias":"作业屠夫",
  4.     "girlfriend":[
  5.                 {"name":"芙蓉姐姐","age":19},
  6.                 {"name":"小月月","age":20}
  7.      ],
  8.      "hobby":["抽烟","喝酒","把妹"],
  9.      "baobiao":[
  10.                 {"name":"李强强","alias":"小而强大"},
  11.                 {"name":"孙珊珊","alias":"美丽动人纯情妞"},
  12.                 {"name":"张涛","alias":"外纯内骚"}
  13.      ],
  14.      "children":null
  15. }


现在我们要查询这条文档,很多童鞋会这样做:

       db.user.find({"children":null})

而我们这样做的后果,是会显示所有的文档,因为其他文档当中没有”children“键,这样也会被查询出来,

所以我们需要加一个判断:”如果‘children’的值为null,并且‘children’键存在“:

       db.user.find({"children":{'$in':[null],'$exists':1}})

这就需要我们配合$in来使用查询。

又如:

       我们需要查询”girlfriend“键中包含name为”凤姐“的所有文档:

这个需求当中的”girlfriend“键是一个数组,因此我们需要在数组当中去搜索name包含”凤姐“的元素,我们这里使用$all:

      db.user.find({"girlfriend.name":{'$all':['凤姐']}})

$all后面可以有多个值,来进行搜索同时包含多个值的数组。

如果我们要查询满足用户的"girlfriend"个数为3个的文档,我们可以使用'$size':

      db.user.find({"girlfriend":{'$size':3}})

如果我们要列出满足某个条件的文档的”baobiao“键的前两条内容,我们需要使用$slice:

      db.user.find({条件},{"baobiao":{'$slice':2}})

那自然,返回后两条为:

      db.user.find({条件},{"baobiao":{'$slice':-2}})

如果只返回中间的一条

     db.user.find({条件},{"baobiao":{'$slice':[1,1]}})

中括号内的第一个元素为略过几个元素,第二个元素是列出几条元素

又如:

      如果我们要查询"girlfriend"键中的"name"为”芙蓉姐姐“的,并且”age“键大于19的文档,要怎么做?

我们可以使用$elemMatch来匹配:

     db.user.find({"girlfriend":{'$elemMatch':{"age":{'$gt':19},"name":"芙蓉姐姐"}}})

$elemMatch的功能为:匹配数组当中的单个内嵌文档的限定条件。

再比如说,捷哥今天去买了五篮子水果,假设每篮子水果一个文档对象:

  1. {
  2.         "apple":7,
  3.         "banana":5,
  4.         "peach":10,
  5.         "watermelon":1
  6. }
  7. <-------------------------------------->
  8. {
  9.         "grape":7,
  10.         "banana":7,
  11.         "peach":10,
  12.         "watermelon":1
  13. }
  14. <-------------------------------------->
  15. {
  16.         "apple":7,
  17.         "banana":10,
  18.         "grape":10,
  19.         "watermelon":1
  20. }
  21. <-------------------------------------->
  22. {
  23.         "apple":3,
  24.         "orange":15,
  25.         "peach":5,
  26.         "watermelon":5
  27. }
  28. <-------------------------------------->
  29. {
  30.         "apple":7,
  31.         "banana":5,
  32.         "peach":10,
  33.         "watermelon":1
  34. }
  35. <-------------------------------------->


我们现在需要查询出这五篮水果中的任意两种水果的数量相同的水果篮,显然用我们前面所学的所有匹配内容的魔术方法都无法匹配,我们这里需要用到一个万能的魔术方法:


$where,因为MongoDB的客户端是JS引擎,所以我们可以使用JS代码来实现匹配:  

  1. db.fruit.find({'$where':function(){
  2.                  for(i in this){
  3.                       for(j in this){
  4.                            if(this[i]==this[j] && i!=j){
  5.                                   return true;
  6.                            }
  7.                       }
  8.                  }
  9.                  return false;
  10.               }
  11.            }
  12.           )


$where几乎可以实现所有的匹配条件,但是效率很低,所以不建议使用,除非有特别难匹配的条件,我们可以偶尔使用$where。


除find()方法外,MongoDB还提供一个查询方法,是findOne()方法,它的作用是只列出满足条件的文档中的一条,使用方法与find()方法完全一样,这里就不多说了。


至此,MongoDB的增、删、改、查的方法我们都已经掌握,但是我们怎样用PHP连接MongoDB数据库呢,童鞋们别急,下文我将会给家详细讲解,MongoDB数据库的游标,索引,以及怎样使用PHP连接MongoDB数据库来做一个小型的BBS论坛。
阅读(1118) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~