如何使用聚合从 mongodb 中的两个集合中查询?
Posted
技术标签:
【中文标题】如何使用聚合从 mongodb 中的两个集合中查询?【英文标题】:How to query from two collections in mongodb using aggregate? 【发布时间】:2020-09-19 05:09:52 【问题描述】:我的 mongoDB 中有以下两个集合:
产品:
[
"_id": "5ebb0984e95e3e9e35aab3bf",
"name": "Product 1",
"brand": "ABC",
"code": "7891910000190",
"description": "Lorem Ipsum"
,
"_id": "5ebdb9f3d943ae000a4a9714",
"name": "Product 2",
"brand": "DEF",
"code": "7891910000190",
"description": "Lorem Ipsum"
]
库存商品:
[
"_id": "5ed0586b7f2cfe02387d0706",
"companyId": "5ed0491bf9a892a5fd9b4d9b",
"branchId": "5ed049a8f9a892a5fd9b4d9e",
"inventoryId": "5ed04d01e9e43cee79734b95",
"productId": "5ebb0984e95e3e9e35aab3bf"
,
"_id": "5ed058da75e4e01013f5779d",
"companyId": "5ed0491bf9a892a5fd9b4d9b",
"branchId": "5ed049a8f9a892a5fd9b4d9e",
"inventoryId": "5ed04cede9e43cee79734b93",
"productId": "5ebb0984e95e3e9e35aab3bf"
,
"_id": "5ed059483da3bafccb34cec3",
"companyId": "5ed0491bf9a892a5fd9b4d9b",
"branchId": "5ed049a8f9a892a5fd9b4d9e",
"inventoryId": "5ed04d01e9e43cee79734b95",
"productId": "5ebb0984e95e3e9e35aab3bf"
]
我想得到以下结果:
[
"_id": "5ed0586b7f2cfe02387d0706",
"data":
"_id": "5ebb0984e95e3e9e35aab3bf",
"brand": "ABC",
"code": "7891910000190",
"description": "Lorem Ipsum",
"name": "Product 1",
,
"_id": "5ed059483da3bafccb34cec3",
"data":
"_id": "5ebb0984e95e3e9e35aab3bf",
"brand": "ABC",
"code": "7891910000190",
"description": "Lorem Ipsum",
"name": "Product 1",
]
我的 NodeJS 和 MongoDB 聚合如下所示:
const mongoose = require("mongoose");
const StockGoods = mongoose.model("StockGoods");
ObjectId = require("mongodb").ObjectID;
exports.getProducts = async (companyId, branchId, inventoryId) =>
const response = await StockGoods.aggregate([
$match:
companyId: new ObjectId("5ed0491bf9a892a5fd9b4d9b"), // new ObjectId(companyId)
inventoryId: new ObjectId("5ed04d01e9e43cee79734b95"), // new ObjectId(inventoryId)
branchId: new ObjectId("5ed049a8f9a892a5fd9b4d9e"), // new ObjectId(branchId)
,
,
$lookup:
from: "products",
localField: "productId",
foreignField: "_id",
as: "inventory_docs",
,
,
$project:
data: "$inventory_docs",
,
,
$unwind: "$data" ,
]);
return response;
;
这是同一个数据库和上面描述的聚合函数,你可以检查这个:https://mongoplayground.net/p/FRgAIfO2bwh。
但是,当我使用 nodejs 时,这个函数聚合不起作用。 我的 API 不返回任何内容(空数组)。
怎么了?
【问题讨论】:
欢迎来到 SO。这不是 MongoDB 的工作方式。您提供的语法是 SQL。链接:docs.mongodb.com/manual/tutorial 嗨@DzenisH。 ,我包括了我的 mongoDB 聚合,但这不起作用。你能帮帮我吗? 可能是您的 $match 检查它们是否是 ObjectID,顺便说一下,您应该在 $lookup 之前进行 $match @Koodies 我更新了我的代码,但它仍然无法正常工作:( 您是否检查过 $match: companyId: "5ed0491bf9a892a5fd9b4d9b", inventoryId: "5ed04d01e9e43cee79734b95", branchId: "5ed049a8f9a892a5fd9b4d9e", , 是 ObjectID("5ed0491bf9a892a5fd9a48f) 【参考方案1】:[已解决]
问题出在方案中:
companyId:
type: String,
required: true,
,
正确的是:
companyId:
type: Schema.Types.ObjectId,
required: true,
,
【讨论】:
【参考方案2】:这里的问题是您在集合中存储数据的方式...... StockGoods 集合具有 companyId、inventoryId 和 branchId 作为字符串,但聚合正在寻找符合条件的 ObjectId aee:
$match:
companyId: new ObjectId("5ed0491bf9a892a5fd9b4d9b"), // new ObjectId(companyId)
inventoryId: new ObjectId("5ed04d01e9e43cee79734b95"), // new
ObjectId(inventoryId)
branchId: new ObjectId("5ed049a8f9a892a5fd9b4d9e"), // new ObjectId(branchId)
,
根据您存储在数据库中的数据,您需要使用字符串更新匹配项。
所以下面的聚合对你有用..
[
"$match":
"companyId": "5ed0491bf9a892a5fd9b4d9b",
"inventoryId": "5ed04d01e9e43cee79734b95",
"branchId": "5ed049a8f9a892a5fd9b4d9e"
,
"$lookup":
"from": "products",
"localField": "productId",
"foreignField": "_id",
"as": "inventory_docs"
,
"$project":
"data": "$inventory_docs"
,
"$unwind": "$data"
]
您可以在 Compass Aggregator 选项卡中进行测试
【讨论】:
以上是关于如何使用聚合从 mongodb 中的两个集合中查询?的主要内容,如果未能解决你的问题,请参考以下文章
mongodb 如何把从一个集合中的查询结果 插入到一个新的集合