node.js - 如何在mongodb中查询多个集合?
问题描述
- 我有
user collection
一个_id
字段。 - 用户可以订阅 api 密钥,因此
userID
存储在subscription collection
- 另一个集合
Api
是有subscriptionID
订阅集合:
{
"_id":ObjectId("60924ec559bedd45dd74bd61"),
"userID":ObjectId("6090f048536d345a024b8b60")
}
{
"_id":ObjectId("609141bd392194fde3ba7cf6"),
"userID":ObjectId("6090f048536d345a024b8b60")
}
{
"_id":ObjectId("609141bd392194fde3ba7c54"),
"userID":ObjectId("6090f048536d345a024b8bc2")
}
api集合:
{
"_id":ObjectId("60924e7426ed2445aab2fc7f"),
"subscriptionID":ObjectId("609143fb036c8a007a5e6a61")
}
{
"_id":ObjectId("60924ec559bedd45dd74bd61"),
"subscriptionID":ObjectId("609141bd392194fde3ba7cf6")
}
{
"_id":ObjectId("60924ec559bedd45dd74bd68"),
"subscriptionID":ObjectId("609141bd392194fde3ba7c54")
}
现在我想让所有api keys
用户都使用userID
意味着我将通过Api collection find subscriptionID
=> 然后go to the subscription collection
和 =>match the userID with the provided userID
注意 - api 集合中的订阅 ID 是唯一的(订阅只有一个 api 密钥)用户 ID 在订阅集合中不是唯一的。
input: userID - 6090f048536d345a024b8b60
output: first two api documents
解决方案
您实现 MongoDB 模式的方式是一种非常糟糕的做法。尝试将键嵌入到您想要直接引用其他集合的任何位置。
下面的查询可以工作,但如果要查找的记录数非常多,则会消耗大量时间。
db.getCollection('user').aggregate([
{
"$match": {
"_id" : {
"$in": [
ObjectId("6090f048536d345a024b8bc2"),
ObjectId("6090f048536d345a024b8b60")]
}
}
},
{
"$lookup": {
"from": "subscription",
"let": {"u_id": "$_id"},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": ["$userID", "$$u_id"],
}
}
},
{
"$project": {
"_id": 1
}
},
],
"as": "subscriptionData"
}
},
{
"$unwind": {
"path": "$subscriptionData",
"preserveNullAndEmptyArrays": false,
}
},
{
"$lookup": {
"from": "api",
"let": {"sub_id": "$subscriptionData._id"},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": ["$subscriptionID", "$$sub_id"],
}
}
},
{
"$project": {
"_id": 1
}
},
],
"as": "apiData"
}
},
{
"$unwind": {
"path": "$apiData",
"preserveNullAndEmptyArrays": false,
}
},
{
"$group": {
"_id": "$_id",
"subscriptionIds": {"$addToSet": "$subscriptionData._id"},
"apiIds": {"$addToSet": "$apiData._id"},
},
},
])
此查询为提供的输入样本返回以下输出。
[
{
"_id" : ObjectId("6090f048536d345a024b8b60"),
"subscriptionIds" : [
ObjectId("609141bd392194fde3ba7cf6")
],
"apiIds" : [
ObjectId("60924ec559bedd45dd74bd61")
]
},
{
"_id" : ObjectId("6090f048536d345a024b8bc2"),
"subscriptionIds" : [
ObjectId("609141bd392194fde3ba7c54")
],
"apiIds" : [
ObjectId("60924ec559bedd45dd74bd68")
]
}
]
推荐阅读
- prestashop - 如何用 %% 翻译字符串
- python - 为什么 cv2.bilateralFilter 对于不同的数据类型表现如此不同?
- spyder - QGIS,gdal 从 conda forge 安装,但 Spyder 中没有代码完成绑定
- html - 使用 CSS 将水平表格转换为垂直表格
- r - 如何使用 gganimate 使注释出现在特定帧上?
- asp.net-core - 使用 Windows 身份验证拦截未经身份验证的请求
- duktape - 在 ECMAscript throw() 之后如何获取错误对象?
- sqlite - 如何从 SQLite 中的数据库表中选择最近的日期?
- python - 将 HTML 表转换为 JSON (Python)
- firebase - 使用自动生成的 ID 将文档添加到 Firestore,并且 ID 具有特定长度