我叫Mongo,收了“查询基础篇”,值得你拥有

这是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: 单行匹配模式,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符(\n),只能显式位于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:"[^\\s\u4e00-\u9fa5]"}}})
// 只查询出 程序员修炼之旅 一条数据

03:小结

     好了,这一篇就先总结到这,通过本篇文章的总结,对mongodb的单个查询符操作已经有了比较清晰的认知和实操,当然查询实际使用不仅仅是这么简单的,还有单个查找组合的逻辑查询,已经对应的其它的函数(条数、分页查询等),后续专门拿一篇文章来总结分享。欢迎持续关注。

 

END
原创不易,感谢扫描支持,获取更多精彩,谢谢:

点一个推荐,你最好看