设为首页 收藏本站
查看: 1328|回复: 0

[经验分享] MongoDB学习 (五):查询操作符(Query Operators).1st

[复制链接]

尚未签到

发表于 2015-7-6 09:49:28 | 显示全部楼层 |阅读模式
    本文地址:http://www.iyunv.com/egger/archive/2013/05/04/3059374.html   欢迎转载 ,请保留此链接๑·́ ₃·̀๑!  
  查询操作符(Query Operators)可以让我们写出复杂查询条件,让我们使用的过程更加灵活。
  官方文档中使用的“field”单词,RDBMS中是字段的意思,但是MongoDB作为文档数据库,使用的BSON格式作为数据存储格式。field对应key,我这里还是把他翻译成“字段”而不是“键”。若有不妥,请指出。

  演示数据:
  我们将实际操作下。先向集合inventory插入3条数据,文档内容如下:


  {"name":"t1","amount":16,"tags":[ "school", "book", "bag", "headphone", "appliances" ]}
  {"name":"t2","amount":50,"tags":[ "appliances", "school", "book" ]}
  {"name":"t3","amount":58,"tags":[ "bag", "school", "book" ]}
DSC0000.png

比较查询操作符 Comparison Query Operators

  $all



语法: { field: { $all: [  ,  ... ] }
  field:文档中键的名称(不使用双引号)。
  匹配那些指定键的键值中包含数组,而且该数组包含条件指定数组的所有元素的文档。



db.inventory.find( { tags: { $all: [ "appliances", "school", "book" ] } } )
    查询出在集合inventory中 tags键值包含数组,且该数组中包含appliances、school、 book元素的所有文档  ,因此该查询将匹配tags键值包含如下任意数组的所有文档。



[ "school", "book", "bag", "headphone", "appliances" ]
[ "appliances", "school", "book" ]
  执行上面的查询语句,
DSC0001.png




    文档中键值类型不是数组,也可以使用$all操作符进行查询操作,如下例所示:




//查询结果是相同的,匹配amount键值等于50的文档
db.inventory.find( { amount: {$all:[50]}} )
db.inventory.find( { amount: 50}} )
   DSC0002.png   

  $gt



语法:{field: {$gt: value} }
  匹配键值大于指定值的所有文档。
  

  $gte



语法:{field: {$gte: value} }
  匹配键值不小于指定值的所有文档。
  

  $lt



语法:{field: {$lt: value} }
  匹配键值小于指定值的所有文档。
  

  $lte



语法:{field: {$lte: value} }
  匹配键值不大于指定值的所有文档。



//下面将查询amount键值大于50的文档:
db.inventory.find( { amount: { $gt: 50 } } )
//下面将查询amount键值不小于(大于等于)50的文档:
db.inventory.find( { amount: { $gte: 50 } } )
//下面将查询amount键值小于50的文档:
db.inventory.find( { amount: { $lt: 50 } } )
//下面将查询amount键值不大于(小于等于)50的文档:
db.inventory.find( { amount: { $lte: 50 } } )
DSC0003.png
DSC0004.png
  

  $in



语法: { field: { $in: [, , ...  ] } }
  匹配键值等于指定数组中任意值的文档。类似sql中in.
  

  $nin



语法: { field: { $nin: [ ,  ...  ]} }
  匹配键不存在或者键值不等于指定数组的任意值的文档。
  查询出amount键值为16或者50的文档:



db.inventory.find( { amount: { $in: [ 16, 50 ] } } )
DSC0005.png



//查询出amount键值不为16或者50的文档
db.inventory.find( { amount: { $nin: [ 16, 50 ] } } )
//查询出qty键值不为16或50的文档,由于文档中都不存在键qty,所以返回所有文档
db.inventory.find( { qty: { $nin: [ 16, 50 ] } } )
DSC0006.png
  

  $ne



语法: {field: {$ne: value} }
  匹配键值不等于指定值的文档。
  查询出amount键值不等于58的文档:



db.inventory.find( { amount: { $ne: 58 } } )
//$nin查询结果相同
db.inventory.find( { amount: { $nin: [58] } } )
DSC0007.png
  

逻辑查询操作符 Logical Query Operators

  $and



语法: { $and: [ {  }, {  } , ... , {  } ] }
  $and 指定一个至少包含两个表达式的数组,选择出满足该数组中所有表达式的文档。$and操作符使用短路操作,若第一个表达式的值为“false”,余下的表达式将不会执行。



//选择name为“t1”,amount值小于50的文档数据
db.inventory.find({ $and: [ { name: "t1" }, { amount: { $lt:50 } } ] } )
DSC0008.png
  对于下面使用逗号分隔符的表达式列表,MongoDB会提供一个隐式的$and操作:



//等同于{ $and: [ { name: "t1" }, { amount: { $lt:50 } } ] }
db.inventory.find({ name: "t1" , amount: { $lt:50 }} )
DSC0009.png

  $nor



语法: { $nor: [ {  }, {  }, ... {  } ] }
  $nor执行逻辑NOR运算,指定一个至少包含两个表达式的数组,选择出都不满足该数组中所有表达式的文档。



//选择name不为“t1”,amount值不小于50的文档数据
db.inventory.find( { $nor: [ { name: "t1" }, { qty: { $lt: 50 } } ] } )
DSC00010.png



//若是文档中不存在表达式中指定的键,表达式值为false; false nor false 等于 true,所以选择集合所有文档
db.inventory.find( { $nor: [ { sale: true }, { qty: { $lt: 50 } } ] } )
DSC00011.png
  

  $not



语法: { field: { $not: {  } } }
  $not执行逻辑NOT运算,选择出不能匹配表达式的文档 ,包括没有指定键的文档。
  $not操作符不能独立使用,必须跟其他操作一起使用(除$regex)。



//选择amount值不大于50的文档数据
db.inventory.find( { amount: { $not: { $gt: 50 } } } )
DSC00012.png



//指定的键gty,文档中都不存在无法匹配表示,所以返回集合所有文档数据。
db.inventory.find( { gty: { $not: { $gt: 50 } } } )
DSC00013.png
  

  $or



语法: { $or: [ {  }, {  }, ... , {  } ] }
  $or执行逻辑OR运算,指定一个至少包含两个表达式的数组,选择出至少满足数组中一条表达式的文档。



//选择amount的键值大于50或者name的键值为t1的文档
db.inventory.find( { $or: [ { amount: { $gt: 50 } }, { name: "t1" } ] } )
DSC00014.png
  

元素查询操作符 Element Query Operators

  $exists



语法: { field: { $exists:  } }
  如果$exists的值为true,选择存在该字段的文档;若值为false则选择不包含该字段的文档。



//查询不存在qty字段的文档(所有文档)
db.inventory.find( { qty: { $exists: false } })
//查询amount字段存在,且值不等于16和58的文档
db.inventory.find( { amount: { $exists: true, $nin: [ 16, 58 ] } } )
DSC00015.png
  如果该字段的值为null,$exists的值为true会返回该条文档,false则不返回。



//向集合中插入一条amount键值为null的文档
{"name":"t4","amount":null,"tags":[ "bag", "school", "book" ]}
//0条数据
db.inventory.find( { amount: { $exists: false } } )
//所有的数据
db.inventory.find( { amount: { $exists: true } } )
DSC00016.png
  

  $mod



语法: { field: { $mod: [ divisor, remainder ]} }
  匹配字段值对(divisor)取模,值等于(remainder)的文档。



//选择集合中 amount 字段的值为 4 的 0 次模数的所有文档,例如 amount 值等于 16 的文档
db.inventory.find( { amount: { $mod: [ 4, 0 ] } } )
DSC00017.png
  有些情况下,我们可以使用$mod操作符替代使用求模表达式的$where操作符,因为后者代价昂贵。



db.inventory.find( { $where: "this.amount % 4 == 0" } )
DSC00018.png
  注意:返回结果怎么不一样。因为有一条文档的amount键值为null,javascript中null进行数值转换,会返回。所以该条文档匹配$where操作符求模式了表达式。当文档中字段值不存在null,就可以使用$mod替代$where的表达式.

  $type



语法: { field: { $type:  } }
    选择字段值为指定的BSON数据类型的文档.使用下面类型对应的编号:

类型类型编号
Double 双精度1
String 字符串2
Object 对象3
Array 数组4
Binary data二进制对象 5
Object id 对象id7
Boolean布尔值 8
Date 日期9
Null 未定义10
Regular Expression 正则表达式11
JavaScript JavaScript代码
13
Symbol 符号14
JavaScript (with scope) JavaScript代码(带范围)15
32-bit integer 32 位整数16
Timestamp 时间戳17
64-bit integer 64 位整数18
Min key 最小键255
Max key 最大键127
  如果文档的键值是一个数组。那么$type将对数组里面的元素进行类型匹配而不是键值数组本身。



db.inventory.find( { tags: { $type : 4 } } )
//如果想检查键值的类型是否为数组类型,使用$where操作符
db.inventory.find( { $where : "Array.isArray(this.tags)" } )
DSC00019.png
  下面例子展示了文档中类型(包括MinKey 和MaxKey):



db.type.insert( {x : 3});
db.type.insert( {x : 2.9} );
db.type.insert( {x : new Date()} );
db.type.insert( {x : true } );
db.type.insert( {x : MaxKey } )
db.type.insert( {x : MinKey } )
> db.type.find()
{ "_id" : ObjectId("5185f9cfa1adf7d5f458505e"), "x" : 3 }
{ "_id" : ObjectId("5185f9cfa1adf7d5f458505f"), "x" : 2.9 }
{ "_id" : ObjectId("5185f9cfa1adf7d5f4585060"), "x" : ISODate("2013-05-05T06:18:
55.751Z") }
{ "_id" : ObjectId("5185f9cfa1adf7d5f4585061"), "x" : true }
{ "_id" : ObjectId("5185f9cfa1adf7d5f4585062"), "x" : { "$maxKey" : 1 } }
{ "_id" : ObjectId("5185f9d0a1adf7d5f4585063"), "x" : { "$minKey" : 1 } }
  要查询的字段值为MinKey,使用下面的语法:



db.collection_name.find( { field: { $type: -1 } } )
DSC00020.png
  
  

JavaScript查询操作符  JavaScript Query Operators

  $regex
  $regex操作符查询中可以对字符串的执行正则匹配。 MongoDB使用Perl兼容的正则表达式(PCRE)库来匹配正则表达式.
  可以使用正则表达式对象或者$regex操作符.
  



//查询name键值以“4”结尾的文档
db.inventory.find( { name: /.4/i } );
db.inventory.find( { name: { $regex: '.4', $options: 'i' } } );
DSC00021.png

  $options ($regex 提供四个选项标志)


  • i   如果设置了这个修饰符,模式中的字母会进行大小写不敏感匹配。
  • m   默认情况下,PCRE 认为目标字符串是由单行字符组成的(然而实际上它可能会包含多行).如果目标字符串 中没有 "\n"字符,或者模式中没有出现“行首”/“行末”字符,设置这个修饰符不产生任何影响。
  • s    如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个修饰符,点号不匹配换行符。
  • x    如果设置了这个修饰符,模式中的没有经过转义的或不在字符类中的空白数据字符总会被忽略,并且位于一个未转义的字符类外部的#字符和下一个换行符之间的字符也被忽略。 这个修饰符使被编译模式中可以包含注释。 注意:这仅用于数据字符。 空白字符 还是不能在模式的特殊字符序列中出现,比如序列 。
  注:JavaScript只提供了i和m选项,x和s选项必须使用$regex操作符。
  

  $where
  $where操作符功能强大而且灵活,他可以使用任意的JavaScript作为查询的一部分,包含JavaScript表达式的字符串或者JavaScript函数。
  最典型的应用就是比较文档中的两个键的值是否相等.



//插入两条数据
db.fruit.insert({"apple":1, "banana": 4, "peach" : 4})
db.fruit.insert({"apple":3, "banana": 3, "peach" : 4})
  查找出banana等于peach键值的文档(4种方法):



//字符串形式
db.fruit.find( { $where: "this.banana == this.peach" } )
db.fruit.find( { $where: "obj.banana == obj.peach" } )
//函数形式
db.fruit.find( { $where: function() { return (this.banana == this.peach) } } )
db.fruit.find( { $where: function() { return obj.banana == obj.peach; } } )
DSC00022.png
  查出文档中存在的两个键的值相同的文档。



>db.fruit.find({$where:function () {
for (var current in this) {
for (var other in this) {
if (current != other && this[current] == this[other]) {
return true;
}
}
}
return false;
}});
DSC00023.png
  不是非常必要时,一定要避免使用"$Where"査询,因为它们在速度上要比常规査询慢很多。每个文档都要从BSON转换成JavaScript对象,然后通过"$where"的表达式来运行。同样还不能利用索引。所以,只在走投无路时才考虑"$where"这种用法。

内容参考:

1.http://docs.mongodb.org/manual/reference/operator/


2.取模运算和求余运算的区别

3.模式修饰符
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-83717-1-1.html 上篇帖子: MongoDB学习(二):数据类型和基本概念 下篇帖子: 在MongoDB的MapReduce上踩过的坑
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表