MENU

mongoose查询笔记

December 15, 2022 • 笔记,js

API 概览

  • find - 异步查找表中所有符合查询条件的数据文档。(查找多条)
  • findOne - 异步查找表中第一条符合查询条件的数据文档。(查找一条)
  • findMany - 异步查找表中所有符合查询条件的数据文档。(查找多条)
  • where - 异步查找表中所有符合查询条件的数据文档,以链式的方式进行查找。(查找多条)
  • findById - 根据 id 异步查询指定数据文档(查找一条)

例子

/* 三个效果等价相同的写法 */
model.find().where("name","Yesifang").then(docs=>console.log(docs))
model.find().where("name",/^Yesifang$/).then(docs=>console.log(docs))
model.find().where("name").equals("Yesifang").then(docs=>console.log(docs))
/* 链式查询 */
model.find()
    .where("name").equals("Yesifang")
    .where("age").gte(18).lte(150)
    .then(docs=>console.log(docs))
model.find({ // 以上链式查询的等价于
    name:"Yesifang",
    age:{$gte:18,$lte:150}
}).then(docs=>console.log(docs))

查询条件

直接条件

let conditions1 = { // 查询name字段值为"Yesifang"的数据文档
    name:"Yesifang"
}
let conditions2 = { // 查询age字段值为20的数据文档
    age:20
}
let conditions3 = { // 查询name字段值为"Yesifang",并且age字段的值为20的数据文档
    name:"Yesifang",
    age:20
}

比较条件

  • $eq - 等于(equal)
  • $ne - 不等于(not equal)
  • $gt - 大于(great then)
  • $gte - 大于等于(great then equal)
  • $lt - 小于(less then)
  • $lte - 小于等于(less then equal)
  • $in - 存在(in)
  • $nin - 不存在(not in)

*以上使用方式均为: 字段:{运算符 + 表达式}

{age:{$lt:20}} //年龄小于20的数据

{language:{$in:["html","javascript","python","php","java"]}}

逻辑运算

  • $and - 与(and),使用方式:$and:{字段:{运算符 + 表达式}}
  • $or - 或(or),使用方式:$or:{字段:{运算符 + 表达式}}
  • $nor - 非或(not or),使用方式:$nor:{字段:{运算符 + 表达式}}
  • not - 非(not),使用方式: 字段:{$not:{运算符 + 表达式}}
{name:{$not:{$eq:"Yesifnag"}}} 

{$or:[{name:"Yesifang"},{age:20}]} 

元素查询

  • $exists - 存在
  • $type - 类型
{name:{$exists:true}} // name字段存在的数据文档
{name:{$exists:false}} // name字段不存在的数据文档

{name:{$type:"string"}} // name字段数据类型为String的数据文档(别名只有在3.6版本以上的mongodb才支持)
{name:{$type:2}} // name字段数据类型为String的数据文档(使用类型的编号效果和别名一样)
名称编号(mongodb version *)别名(mongodb version >= 3.6)
Double1“double”
String2“string”
Object3“object”
Array4“array”
Binary data5“binData”
Undefined6“undefined”
ObjectId7“objectId”
Boolean8“bool”
Date9“date”
Null10“null”
Regular Expression11“regex”
DBPointer12“dbPointer”
JavaScript13“javascript”
Symbol14“symbol”
JavaScript(with scope)15“javascriptWithScope”
32-bit integer16“int”
Timestamp17“timestamp”
64-bit integer18“long”
Decimal12819“decimal”
Min key-1“minKey”
Max key127“maxKey”

$mod

取余运算符。查找满足取余表达式的数据文档。值为 array

{age:{$mod:[2,1]}} // age字段的数据值对2取余为1的数据文档

$regex

正则匹配运算符。查找满足正则表达式的数据文档。值为:string | regExp

{url:{$regex:/^https:\/\/.+$/,$options:"i"}} // url字段数据为https://开头的(大小写不敏感)

$options

正则匹配的选项,可选项有:

  • “i” - 大小写不敏感模式
  • “m” - 多行模式
  • “x” - 忽略空白符
  • “s” - 允许点字符(通配符). 匹配换行符

数组查询运算符

数组查询运算符专门针对数据类型为数组的字段。

  • $all - 全部存在(数组包含所有指定的数据,$and 运算符单一字段升级版),使用方式: 字段:{运算符 + 表达式}
  • $elemMatch - 数组元素匹配(匹配拥有满足条件的数组元素的数组所在的数据文档),使用方式: 字段:{运算符 + 表达式}
  • $size - 数组的元素总数(数组中元素总个数,即:array.length),使用方式: 字段:{运算符 + 表达式}
$all
{language:{$all:["html","javascript","nodejs"]}} // language字段数组中同时包含含"html"、"javascript"、"nodejs"的数据文档
$elemMatch
{language:{$elemMatch:{$eq:"nodejs",$eq:"php"}} // language字段数组中拥有"nodejs"或"php"中任意一个的数据文档
$size
{language:{$size:2}} // language字段数组元素为2的数据文档
注意
  • 数组查询运算符,只能够用于数据类型为数组的字段。
  • 除了数组查询运算符外的而其他查询运算符,是所有数据类型的字段都可以使用。
  • 数据类型为数组的字段在使用除了数组查询运算符外的其他运算符时。使用查询条件的每个子条件依次匹配数组的每个数组项,当所有子条件在数组中存在有满足它的数组项时,判定该数组满足查询条件。
model.find({arr:{$gte:18}}) // 如果arr字段是一个数组字段,则将会对数组的各个项都进行查询条件的的监测,只要数组中存在一个满足查询条件的项,则表示这整个数组所在的字段就,都符合查询条件。
/* 例 */
// 表
{_id:"1", name:"Yesifang", arr:[10,20,30]}
{_id:"2", name:"Xiaoming", arr:[10,15,17]}
{_id:"3", name:"Xiaohong", arr:[5,10,302]}

// 查询
model.find({
    arr:{$gte:18, $lte:150}
}).then(docs=>{console.log(docs)})
// 查询结果
{_id:"1", name:"Yesifang", arr:[10,20,30]}
{_id:"2", name:"Yesifang", arr:[5,10,302]}
// 分析
1 先使用查询条件中的第一个子条件:{$gte:18}匹配数组中是否有一个数组项的值 >=18,所以找到了arr:[10,20,30]的第二项(20)。
2. 再使用查询条件中的第二个子条件:{$lte:150}匹配数组中是否有一个数组项的值 <=155,所以找到了arr:[10,20,30]的第一项(10)。
3. 两个子条件都在数组中有一个满足它的数组项,那么这个数组满足查找条件,保留这个数据文档,继续下一个数据文档的查询。
4. 重复上述三个步骤,完成表中所有文档的查找。

投影查询

保留所需字段

/* 表 */
{_id:"001",name:"Yesifang",age:20,pwd:"123456",__v:0}

/* string */
findOne({},
    "-_id -__v -pwd"
).then(doc=>console.log(doc)) // {name:"Yesifang",age:20}
findOne({},
    // 没有设置_id和__v
    "+name +age -pwd"
).then(doc=>console.log(doc)) // {_id:"001",name:"Yesifang",age:20,__v:0},_id和__v都保留了

/* object */
findOne({},
    {_id:false,__v:false,pwd:false}
).then(doc=>console.log(doc))  // {name:"Yesifang",age:20}
findOne({},
    // 没有设置_id和__v
    {name:true,age:true,pwd:false}
).then(doc=>console.log(doc)) // {_id:"001",name:"Yesifang",age:20},只保留了_id
findOne({},
    {name:1,age:1,pwd:0} // 支持js隐式类型转换,1为true 0为false
).then(doc=>console.log(doc)) // {_id:"001",name:"Yesifang",age:20},只保留了_id