使用 Node.js 进行 MongoDB 查找
$lookup运算符是聚合运算符或聚合阶段,用于根据某些查询将一个集合中的文档连接到同一数据库的另一个集合的文档。这两个集合应该属于同一个数据库。
MongoDB 中的聚合是将来自多个文档的值组合在一起的操作,并且可以对分组的数据执行各种操作以返回单个结果。 $lookup是聚合执行的操作之一。
$lookup 是如何工作的?
我们有两个集合,输入集合(执行 $lookup 的集合)和来自集合(我们从中获取文档以将其连接到输入集合的文档的集合)。
$lookup根据一些查询从“来自集合”中选择文档,然后将它们附加到“输入集合”的文档中的一个单独的数组字段中。它就像 SQL 的左外连接。
使用相等匹配执行 $lookup:
在相等匹配中,对于每个文档,将输入集合文档的任何特定字段的值与每个from 集合文档的任何特定字段的值进行比较 如果它们匹配,则集合文档中的特定内容将附加到单独的数组字段中的输入集合文档。
语法:$lookup运算符
{
$lookup:
{
from: < "from collection" >,
localField: < any field from "input collection" >,
foreignField: < any field from "from collection" >,
as: < attached array field >
}
}
- from:它是包含“ from collection ”名称的字段,从中提取文档以将它们连接到输入集合的文档。
- localField:输入集合的任何字段,其值要与foreignField值进行比较。
- foreignField:它是来自集合的任何字段,其值要与 localField 值进行比较。
- as:存放from集合的匹配文档的数组字段。
安装Mongoose:
第 1 步:您可以访问链接 Install mongoose来安装mongoose模块。您可以使用此命令安装此软件包。
npm install mongoose
第 2 步:现在您可以使用以下命令在文件中导入mongoose模块:
const mongoose = require('mongoose');
数据库:我们已经在我们的数据库 GFG 中创建了名为orders和customers的集合,如下图所示:
创建节点应用程序:
第 1 步:使用以下命令创建package.json :
npm init
第 2 步:创建文件model.js ,其中包含订单和客户集合的模式和模型。
model.js
const mongoose = require('mongoose');
const orderSchema = new mongoose.Schema({
_id: Number,
customerId: Number,
itemName: String
})
const customerSchema = new mongoose.Schema({
_id: Number,
name: String,
city: String
})
const Order = new mongoose.model('order', orderSchema);
const Customer = new mongoose.model('customer', customerSchema);
module.exports = { Order, Customer };
main.js
// Requiring module
const mongoose = require("mongoose");
// Importing Models Order and Customer from model.js
const { Customer, Order } = require("./model");
// Connecting to database
mongoose.connect("mongodb://localhost:27017/GFG", {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
});
// Implementing $lookup for customers collection
Customer.aggregate([
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "customerId",
as: "orders_info",
},
},
// Deconstructs the array field from the
// input document to output a document
// for each element
{
$unwind: "$orders_info",
},
])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
main.js
const mongoose = require("mongoose");
// Model for Order and Customer
const { Customer, Order } = require("./model");
// Connecting to database
mongoose.connect("mongodb://localhost:27017/GFG", {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
});
// Performing multiple query with the help of pipeline
Customer.aggregate([
{
$lookup: {
from: "orders",
let: { custId: "$_id" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$customerId", "$$custId"] },
{ $eq: ["$itemName", "Watch"] },
],
},
},
},
],
as: "orders_info",
},
},
{
$unwind: "$orders_info",
},
])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
第 3 步:使用以下代码创建文件 main.js。
main.js
// Requiring module
const mongoose = require("mongoose");
// Importing Models Order and Customer from model.js
const { Customer, Order } = require("./model");
// Connecting to database
mongoose.connect("mongodb://localhost:27017/GFG", {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
});
// Implementing $lookup for customers collection
Customer.aggregate([
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "customerId",
as: "orders_info",
},
},
// Deconstructs the array field from the
// input document to output a document
// for each element
{
$unwind: "$orders_info",
},
])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
使用以下命令运行main.js :
node main.js
说明:这里将每个客户集合文档的_id字段值与每个订单集合文档的 customerId 字段进行比较,如果匹配,则将该订单集合文档附加到orders_info数组字段中的客户集合文档。
注意:这里$unwind用于从输入文档中解构“orders_info”数组字段以输出每个元素的文档。有了这个,我们将能够看到每个附加的文件。
输出:在控制台中,我们使用 $lookup从集合文档中加入输入集合文档。
当我们从代码中消除$unwind运算符时,我们将得到如下所示的输出:
使用多个连接条件执行 $lookup:
语法:$查找运算符
{
$lookup:
{
from: < “from collection” >,
let: { < var_1 >: < field_1 > , < var_2 >: < field_2 > , …… },
pipeline: < different pipeline stages to be performed of “from” collection >,
as: < attached array field >
}
}
- from:它是包含“from collection”名称的字段,要从中获取文档以将它们加入到输入集合的文档中。
- let:这是一个可选字段。管道不能直接访问“输入”文档字段,因此在 let 变量中我们定义输入文档字段的名称,以在管道中用于执行查询。
- 管道:它是在“来自”集合的文档上运行不同阶段的管道,然后在数组字段中返回结果文档的字段。
- as:存放from集合的匹配文档的数组字段。
笔记:
- 要使用 $let 字段中定义的变量,我们像 $$
一样引用它。 - 在 $match 中使用 $expr运算符来访问变量 $let 字段。
如下所示更改main.js文件并运行以获取结果:
main.js
const mongoose = require("mongoose");
// Model for Order and Customer
const { Customer, Order } = require("./model");
// Connecting to database
mongoose.connect("mongodb://localhost:27017/GFG", {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
});
// Performing multiple query with the help of pipeline
Customer.aggregate([
{
$lookup: {
from: "orders",
let: { custId: "$_id" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$customerId", "$$custId"] },
{ $eq: ["$itemName", "Watch"] },
],
},
},
},
],
as: "orders_info",
},
},
{
$unwind: "$orders_info",
},
])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
使用命令运行main.js :
node main.js
说明:在上面的代码中,我们正在加入来自orders集合的文档,其customerId 的值与 customers集合的_id的值匹配,并且itemName的值为“Watch” 。为了在管道中使用客户集合的_id字段,我们在 let 字段中将其定义为custId 。
注意:这里$unwind用于从输入文档中解构“orders_info”数组字段以输出每个元素的文档。有了这个,我们将能够看到每个附加的文件。
输出:在控制台中,我们正在获取匹配的文档,如下所示:
当我们从代码中消除$unwind运算符时,我们将得到如下所示的输出: