这是mongo第二篇「查询基础篇」,后续会连续更新6篇
mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟着我一起来探索交流。
通过上一篇基础篇的介绍,我相信大家对我有了初步的认识,并且能够简单的使用我了,在使用过程中我相信大家用的最多的还是查询吧,今天我就和大家一起来总结查询基础哪一些事吧。如果有总结的不到位的地方,希望您多多指点。
01:查询简介
查询mongdodb提供了两个方法:find()和findOne(),前者是查询符合要求的所有数据,后者只查询符合要求的第一条数据,两者的参数都一样,具有两个参数,并且两个参数都是选填。
命令格式:db.collection.find(query,projection) ,两个参数都是非必填。
query:是一个查询条件BJSON对象,根据查询条件构建对应的BJSON对象。如:
db.user.find({name:"name对应的值"},{sex:"sex对应的值"})
projection:设置查询需要返回的字段集合,不设置代表返回全部字段,其格式为:{字段名称:是否获取..},当设置为1代表需要获取,注意:_id默认值为1,所以需要查询结果不需要_id,那么需要设置其值为0。
说上去自我感觉还是有点空洞,还是上一个一些实例吧!
数据初始化:
向数据库testdb的user集合初始化如下三条数据
use testdb db.user.insert([{name:"序员修炼之旅",age:2,from: "CTU"}, {name: "mongdo",age:13,from: "USA"}, {name: "C++",from: "USA" ,author:["xiaoxu","xiaozhang"]}])
数据查询实例 :
// 查询全部数据 db.user.find() // 查询结果:返回刚刚初始化的3条数据全部数据 // 查询name=程序员修炼之旅,并且只返回节点 name和from db.user.find({name:"序员修炼之旅"},{_id:0,name:1,from:1}) // 查询结果为: { "name": "序员修炼之旅","from": " CTU" } //查询所有数据,并且只返回节点 name和from db.user.find({},{_id:0,name:1,from:1}) // 查询结果 [{"name": "序员修炼之旅","from": "CTU"}, {"name": "mongdo","from": "USA"}, {"name": "C++","from": "USA"}] // 只查询一条数据,其它查询条件和返回字段两个参数和find方法一直,不在细说 db.findOne()
基础查询小结,通过上面的实例操作,其实我们不难发现:
1、find和findOne使用上一样,findOne查询一条,find查询所有
2、查询的有两个参数,并且两个参数都是非必填
3、projection设置时,_id默认返回,如不返回需要手动设置为0
02:查询条件探索
通过查询简介我们应该对查询有了初识印象,也许你会疑惑,查询就这么简单啊,解决不了实际工作需要啊,比如查询年龄在20-30之间的用户。不急不急,下面的探索专门就是解决这一些问题而来的。
先从简单的单个查询符号说起,掌握了单个查询符号,至于复杂的查询条件就很简单了,就像拼积木一样根据规则组装即可。
单个查询符的命令格式为:db.collection.find({字段:{查询符:值}})
mongodb的单个查询符包括:
比较符(等于[严格来说等于不是一个查询符]、不等于、大于、小于、大于等于、小于等于);
包含符(包含、不包含、全包含);模糊匹配符(左匹配、右匹配、模糊匹配、全部匹配);
元素操作符(字段是否存在、字段值是否为空、字段类型);
集合查询符(长度、子查询);
取模符;
正则表达式。
哈哈声明一下,上面说到的7个查询符是我自己的总结归类,如有不妥之处,多多指点。总结下来,发现查询符号还是蛮多的,下面我们将一一来介绍每一个查询符的使用:下面的实例还是继续沿用上面举例中的数据库操作。
初始化一下数据库:
db.user.insert({name:".net",age:88,author: ["xiaoxu","xiaozhang","xiaoliu"]})
NO.1 【比较符】
符号:$ne (不等于)
说明:和等于刚刚相反,包括没有该字段的文档数据
语法: {field:{$ne:<值>}}
实例:
// 查询from!="USA"的数据 db.user.find({from: {$ne: "USA"}}) // 结果查询出来序员修炼之旅和.net两条数据
符号:$gt(大于)
说明:针对字段类型为数字的文档,其值大于指定值的文档数据
语法:{field:{$gt:<值>}}
实例:
// 查询age>13的数据 db.user.find({age: {$gt:13}}) // 结果只查询出.net一条数据
符号:$gte (大于等于)
说明:针对字段类型为数字的文档,其值大于等于指定值的文档数据
语法:{field:{$gte:<值>}}
实例:
// 查询age>=13的数据 db.user.find({age: {$gte:13}}) // 结果查询出mongo和.net两条数据
符号:$lt(小于)
说明:针对字段类型为数字的文档,其值小于指定值的文档数据
语法: {field:{$lt:<值>}}
实例:
// 查询age<13的数据 db.user.find({age: {$lt:13}}) // 结果只查询出序员修炼之旅一条数据
符号:$lte(小于等于)
说明:针对字段类型为数字的文档,其值小于等于指定值的文档数据
语法: {field:{$lte:<值>}}
实例:
// 查询age<=13的数据 db.user.find({age: {$lte:13}}) // 结果查询出序员修炼之旅和mongo两条数据
NO.2 【包含符】
符号:$in(包含)
说明:如果被查询字段为非集合,被查询字段的值在条件集合里即可;如果被查询的字段为集合,那么被查找的字段只要有一个只包含在条件集合即可。
语法: {field:{$in:[值1,值2..]}}
实例:
// 查询from在["CTU","USA"]的数据 db.user.find({from: {$in:[ "CTU","USA"]}}) // 结果查询出序员修炼之旅、mongo和c++三条数据 // 查询author在["xiaoxu"," xiaowang"]的数据 db.user.find({author:{$in:["xiaoxu","xiaowang"]}}) // 结果查询出序员修炼之旅、mongo两条数据
符号:$nin(不包含)
说明:和包含刚刚相反,查询结果包括两类数据:有该字段,但是该字段的值都在条件集合内的文档数据;没有该字段的文档数据。
语法:{field:{$nin:[值1,值2..]}}
实例:
// 查询from不在["CTU","USA"]的数据 db.user.find({from: {$nin:[ "CTU","USA"]}}) // 结果只查询出 .net 一条数据 // 查询author不在["xiaoliu","xiaowang"]的数据 db.user.find({author:{$nin:["xiaoliu","xiaowang"]}}) // 结果查询出序员修炼之旅、mongdo和c++三条数据
符号:$all(全包含)
说明:和包含很相似,包含是全包含的一个子集,全包含只是被查询字段包含查询条件的所有值。主要使用于字段为集合的文档数据查询
语法:{field:{$all:[值1,值2..]}}
实例:
// 查询author全部包含["xiaoxu","xiaozhang"]的数据 db.user.find({author:{$all:["xiaoxu","xiaozhang"]}}) // 结果查询出c++和.net两数据 // 查询author全部包含["xiaoxu","xiaoliu"]的数据 db.user.find({author:{$all:["xiaoxu","xiaoliu"]}}) // 结果没有一条数据符合要求
NO.3 【模糊匹配符】
模糊查询对应的就是SQL中的like查询,mongodb模糊查询通过/符合来实现,和SQL中的%对应,其实模糊查询就是正则表达式的一个简写方式,废话不多说,直接上案例!
符号:/^X/ (左匹配)
说明:匹配以X开始的所有集合数据
实例:
// 查询name 以 程 开始的集合数据 db.user.find({name:/^序/}) // 结果只查询出 序员修炼之旅 一条数据
符号:/X$/(右匹配)
说明:匹配以X结束的所有集合数据
实例:
// 查询name 以 旅 结束的集合数据 db.user.find({name:/旅$/}) // 结果只查询出 序员修炼之旅 一条数据
符号:/X/ (模糊匹配)
说明:匹配包含X的所有集合数据
实例:
// 查询name 以 程序员 的集合数据 db.user.find({name:/程序员/}) // 结果查询出 序员修炼之旅 一条数据
符号:/^X$/(全匹配)
说明:既以X开头也以X结尾的所有集合数据,其实就是等于X的数据集合;等价于”X”
实例:
// 查询name =序员修炼之旅 的集合数据 db.user.find({name:/^序员修炼之旅$/}) // 结果查询出 序员修炼之旅 一条数据
符号:i(不区分大小写)
说明:在模糊匹配度后面添加i在匹配过程中不区分大小写
实例:
// 查询from中包括t的数据,包括t和T db.user.find({from:/t/i}) // 结果查询出 序员修炼之旅 一条数据
NO.4 【元素操作符】
为了演示效果,查询一条新数据
db.user.insert({name:"java",age:"保密",author:null})
符号:$exists(字段是否存在)
说明:对应的值为bool,当为true:查找存在改字段的文档数据(包括字段的值为空);false:查询不存在改字段的文档数据
语法:{field:{$exists:<boole>}}
实例:
// 查询包含author的集合数据 db.user.find({author:{$exists:true}}) // 查询出c++、.net、java三条数据 // 查询不包含author的集合数据 db.user.find({author:{$exists:false}}) // 查询出序员修炼之旅、mongdo两条数据
符号:null(字段值是否为空)
说明:查询两类数据,不存在节点的文档数据和存在改节点但是数据为null的文档数据。相对$exists:false 多了一类值为null的文档数据
语法:{field: null }
实例:
db.user.find({author: null }) // 查询出序员修炼之旅、mongdo、java三条数据
符号:$type(字段类型)
说明:根据字段的类型来查询,具体的字段类型是一个枚举值,枚举值关系请在网上查询,不在此列举!
语法:{field:{$type:<类型枚举值number>}}
实例:
// 查询age为数值的文档数据 db.user.find({age:{$type:1}}) // 结果查询出 序员修炼之旅、mongdo、.net 三条数据 // 查询age为字符串的文档数据 db.user.find({age:{$type:2}}) // 结果查询出java 一条数据
NO.5 【集合查询符】
初始化一条数据:
db.user.insert({name:"python",author:[{authorName:"王强",date:"2020-11-06"},{authorName:"刘强",date:"2020-11-01"}]})
符号:$size(长度)
说明:针对节点数据为一个子集合的数据,查询对应节点的子集长度
语法:{fild:{$size:<numbr>}}
实例:
// 查询author的长度为3的数据 db.user.find({author:{$size:3}}) // 查询出.net一条数据 // 查询author的长度为1的数据 db.user.find({author:{$size:1}}) // 未查询出任何数据
符号:$elemMatch(子查询)
说明:子查询具体的查询条件和上面的查询条件方式一样,只是做了一个嵌套查询,查询出子查询有数据的文档数据
语法:{fild:{$elemMatch:{子查询条件}}}
实例:
// 查询author中的authorName为王强的数据 db.user.find({author:{$elemMatch:{authorName:"王强"}}}) // 结果查询出python一条数据
子查询扩展
说明:子查询的语法还支持外节点.子节点模式。
语法:{"外节点.子节点":子查询条件}
实例:
// 查询author中的authorName为王强的数据 db.user.find({author.authorName:"王强"}) // 结果查询出python一条数据
NO.6 【取模符】
符号:$mod(取模)
说明:简答的说就是除一个数的余数查询
语法:{fild:{$ mod:[value,value2]}}
实例:
// 查询age除 3 余数为2的数据 db.user.find({age:{$mod:[3,2]}}) // 查询出序员修炼之旅一条数据
NO.7 【正则表达式】
符号:$regex(正则匹配)
说明:mongodb查询中的正则匹配和js中的正则匹配一致,如果会js中的正则匹配就轻松上手。几个关键词及其注意:
1、^ 取反的意思,用特殊的转义字符需要在前面加一个斜杠;
2、通过 ^取反 ,再通过$not取反,就可获得只包含一种类型的数据
\d 数字
\s 空格
\w 数字和字母
语法:{fild:{$ regex:正则表达式, $options: "options值" }}
其中$options可改变匹配规则,是几个固定的枚举值(i,m,x,s),但是不同枚举值可以组合使用,具体枚举值如下:
i: 忽略大小写;
m: 多行匹配模式,会更改^和$元字符的默认行为,分别使用与行的开头和结尾匹配,而不是与输入字符串的开头和结尾匹配。
x: 忽略非转义的空白字符,正则表达式中的非转义的空白字符将被忽略,同时井号(#)被解释为注释的开头注,只能显式位于option选项中。
s: 单行匹配模式,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符( ),只能显式位于option选项中。
// 列举几个平时工作中常用到的查询方式 // 查询 name中包含 字母大写 O的数据,区分大小写 db.user.find({age:{$regex:"O"}}) // 未查询到任何数据 // 查询 name中包含 字母大写 O的数据,不区分大小写 db.user.find({name:{$regex:"O",$options:"$i"}}) // 查询出 mongdo、python两条数据数据 // 查询from字段中以C开始U结尾的数据 db.user.find({from:{$regex:"^C\wU$"}}) // 查询出序员修炼之旅一条数据 // 查询age包含中文的数据 db.user.find({age:{$regex:"[u4e00-u9fa5]"}}) // 结果值查询java 一条数据 // 查询age不包含中文的数据 db.user.find({age:{$not:{$regex:"[u4e00-u9fa5]"}}}) // 查询出来了序员修炼之旅、mongdo、C++、.net、python // 查询name只包含字母的数据,^ 取反的意思 db.user.find({"name":{$not:{$regex:"[^a-zA-z\s]"}}}) // 查询出mongdo、java、python 三条数据 // 查询name只包含汉字的数据,可包含空格 db.user.find({"name":{$not:{$regex:"[^\su4e00-u9fa5]"}}}) // 只查询出 程序员修炼之旅 一条数据
03:小结
好了,这一篇就先总结到这,通过本篇文章的总结,对mongodb的单个查询符操作已经有了比较清晰的认知和实操,当然查询实际使用不仅仅是这么简单的,还有单个查找组合的逻辑查询,已经对应的其它的函数(条数、分页查询等),后续专门拿一篇文章来总结分享。欢迎持续关注。
END
原创不易,感谢扫描支持,获取更多精彩,谢谢:
点一个推荐,你最好看