MongoDB多表连接查询,Mongoose聚合查询
// 依赖模块:mongoose
npm i -S mongoose
简介
一种对MongoDB进行使用多表连接查询的函数
使用方式及字段介绍
model.aggregate(<ConditionSetting>).then(<resolveFunction>).catch(<rejectFunction>)
其中
- ConditionSetting为操作设置
- resolveFunction为执行成功回调函数,可设置形参接收查询结果result
- rejectFunction为执行失败回调函数,可设置形参接收错误报告err
输入的变量值ConditionSetting根据需求可以有不同的输入,个人认为最常见的输入为:
[
{$lookup}, // 多表连接配置
{$unwind}, // 查询结果的字段的拆分
{$addFields},
{$project},
{$match},
{$sort},
{$limit},
{$skip},
[{$count}]
]
因此本次只就以上字段进行解释:
-
$lookup
-
输入值:
{ $lookup: { from:<String>, localField:<String>, foreignField:<String>, as:<String> } }
-
含义解释:对表连接的配置,类似于sql中的join操作,其字段必有:
-
from : 要连接的目标表,类似于sql中的join
-
localField :作为连接参照的本表字段
-
foreignField :作为连接参照的目标表字段,localField和foreignField类似sql多表连接中join后的等值设置—> select [someThing] from [table] join [targetTable] on localField=foreignField
-
as:当连接查询查询出来之后,外表的查询结果会在本表查询结果中开辟一个新的字段进行存储,而字段名就是这个字段设置的,只有一个存储结果时为单独的对象字段,多个结果时为对象数组 :
-
{ "LocalResultField":"FieldValue", ··· [valueOfAs]:[{ // 这里是从另一个表里匹配到的结果 // 注意: // 这条数据有它在另一个表里全部的字段 // 也就相当于是只是把这个匹配到的数据直接从另一个表里搬过来了而已 "otherTable'sField":"FieldValue" ··· }, ··· ] }
-
-
-
-
$unwind
-
输入值:
{ $unwind: <String> /*这里的值和 $lookup 中 as 的值是一样的*/ }
-
含义解释:对$lookup中as中的结果进行拆分操作,具体表现为:如果查询出多个数据,会将查询结果存储的数组进行拆分,使之成为多个单独对象的值:
之前是这样的:
-
{ "LocalResultField":"FieldValue", ··· [valueOfAs]:[/*这里是一个有好多好多好多对象组合成的数组*/] }
-
进行拆分设置后变成了这样:
[ { "LocalResultField":"FieldValue", ··· [valueOfAs]:{/*这里是数组里的其中一个数据*/} }, { "LocalResultField":"FieldValue", ··· [valueOfAs]:{/*这里是数组里的另一个数据*/} }, ··· ]
-
-
$addFields
-
输入值:
{$addFields:{ // 举例 "aaa":"$as.bbb" // 格式 "newFieldName":"$[value Of The As].[Original Name IN Other Table]" }}
-
含义解释:对最终查询结果的结构进行添加新字段操作,如果原本表里没有这个字段,你又要在结果里显示这个字段,那首先要对结果进行添加新字段操作,相当于是将外来字段设置进本表查询结果中
-
-
$project
-
输入值:
{$project:{ "field":1 // “1”表示你要将这个字段在最终结果中显示,没有“0” ··· }}
-
含义解释:对最终查询结果的显示操作,设置了的字段会在最终输出结果中显示,没设置的字段不会显示,这里面设置的字段必须是原本表里拥有的字段,如果原本表里没有的字段必须要先通过 $addFields 进行添加操作才能设置,类似于sql查询语句中的 select 后 from前的部分
-
-
$match
-
输入值:
{$match:{ // 这里输入一些查询条件 // 例子 "aaa":"111" // 格式 "field":"conditionValue" } }
-
含义解释:查询条件,类似于sql查询语句中的where部分
-
-
$sort
-
输入值:
{$sort:{ "field": 1/-1 //“1”表示升序排列,“-1”表示降序排列 }}
-
含义解释:对搜索结果根据选定字段进行排序
-
注意事项:limit,skip,sort的最终执行顺序是:先sort后skip后limit
-
-
$limit
-
输入值:
{$limit:<Number>}
-
含义解释:对输出的结果条目进行指定数量的限制
-
注意事项:limit,skip,sort的最终执行顺序是:先sort后skip后limit
-
-
$skip
-
输入值:
{$skip:<Number>}
-
含义解释:对输出结果跳过指定数目的数据
-
注意事项:limit,skip,sort的最终执行顺序是:先sort后skip后limit
-
-
[$count]
-
输入值:
{$count:<String>}
当然也可以连缀调用
model.aggregate(Condition).count(<String>)
-
含义解释:在总搜索结果中插入新的字段表示对搜索结果的总条目的计数,输入的值只是为了定义这个承载计数结果的字段的名字
-
注意事项:一旦使用了count,则最终只会输出count的计数结果而不会输出查询结果,如果既想要查询结果又想要计数结果可以使用Promise.all
-
最后的注意事项
以上字段的执行顺序是按顺序进行的,因此设置的字段顺序会对最终结果产生影响,例如先插入match后插入lookup的话就会先执行条件查询操作后进行表连接操作