Mongodb 从另一个 collection 中的字段中找到 collection 中的文档
Mongodb find document in collection from field in another collection
我有两个 collection:共享和 Material。
分享:
{
from_id: 2
to_id: 1
material_id: material1
}
Material:
{
_id: material1
organization_id: 2
},
{
_id: material2
organization_id: 1
},
{
_id: material3
organization_id: 1
},
--编辑:
有3个素材,2个属于organization_id(1),1个属于organization_id(2)。 organization_id 不匹配 material1 中的 1(而是属于 material2),但在共享 collection 中,to_id 匹配 1。如果匹配存在,我想找到等于 material_id 共享的 Material 文档 _id 并找到 organization_id 等于 1 的 Material 文档。
我想检查共享 (to_id) 中的字段是否具有等于 Material (organization_id) 中的字段的值,并检查 organization_id等于1,如果有文档从这里存在,再检查一下Material的_id是否等于Sharing的material_id和returnall文件和总数。
如果没有相等的值,我想省略那个结果并发送 object 只有 organization_id 等于 1 并得到这个结果的总数。
现在,我使用 .map() 以一种非常低效的方式来查找它。下面是我的代码:
export const getMaterials = async (req, res) => {
const sharing = await Sharing.find({to_id: 1});
let doneLoad;
try {
if (sharing && sharing.length>0) {
const sharingTotal = await Material.find( {$or: [ {organization_id: 1}, {_id: sharing.map((item) => item.material_id)} ] } ).countDocuments();
const sharingMats = await Material.find( {$or: [ {organization_id: 1}, {_id: sharing.map((item) => item.material_id)} ] } );
res.status(200).json({data: sharingMats});
doneLoad= true;
}
else if (!doneLoad) {
const materialTotal = await Material.find({organization_id: 1}).countDocuments();
const materials = await Material.find({organization_id: 1});
res.status(200).json({data: materials});
}
} catch (error) {
res.status(404).json({ message: error.message });
}
}
我曾尝试使用聚合来获得我想要的结果,但我找不到任何符合我要求的解决方案。任何帮助都会很棒,因为我对使用 mongodb 还很陌生。谢谢。
编辑(期望的结果):
Materials: [
{
_id: material1,
organization_id: 1
},
{
_id: material2,
organization_id: 1
},
{
_id: material3,
organization_id: 1
}
]
您可以在 $lookup
中使用 sub-pipeline 来执行过滤。 $addFields
稍后使用 $size
计数。
db.Sharing.aggregate([
{
"$match": {
to_id: 1
}
},
{
"$lookup": {
"from": "Material",
"let": {
to_id: "$to_id",
material_id: "$material_id"
},
"pipeline": [
{
"$match": {
$expr: {
$or: [
{
$eq: [
"$$to_id",
"$organization_id"
]
},
{
$eq: [
"$$material_id",
"$_id"
]
}
]
}
}
},
{
"$addFields": {
"organization_id": 1
}
}
],
"as": "materialLookup"
}
},
{
"$addFields": {
"materialCount": {
$size: "$materialLookup"
}
}
}
])
这里是Mongo playground供您参考。
我有两个 collection:共享和 Material。
分享:
{
from_id: 2
to_id: 1
material_id: material1
}
Material:
{
_id: material1
organization_id: 2
},
{
_id: material2
organization_id: 1
},
{
_id: material3
organization_id: 1
},
--编辑: 有3个素材,2个属于organization_id(1),1个属于organization_id(2)。 organization_id 不匹配 material1 中的 1(而是属于 material2),但在共享 collection 中,to_id 匹配 1。如果匹配存在,我想找到等于 material_id 共享的 Material 文档 _id 并找到 organization_id 等于 1 的 Material 文档。
我想检查共享 (to_id) 中的字段是否具有等于 Material (organization_id) 中的字段的值,并检查 organization_id等于1,如果有文档从这里存在,再检查一下Material的_id是否等于Sharing的material_id和returnall文件和总数。
如果没有相等的值,我想省略那个结果并发送 object 只有 organization_id 等于 1 并得到这个结果的总数。
现在,我使用 .map() 以一种非常低效的方式来查找它。下面是我的代码:
export const getMaterials = async (req, res) => {
const sharing = await Sharing.find({to_id: 1});
let doneLoad;
try {
if (sharing && sharing.length>0) {
const sharingTotal = await Material.find( {$or: [ {organization_id: 1}, {_id: sharing.map((item) => item.material_id)} ] } ).countDocuments();
const sharingMats = await Material.find( {$or: [ {organization_id: 1}, {_id: sharing.map((item) => item.material_id)} ] } );
res.status(200).json({data: sharingMats});
doneLoad= true;
}
else if (!doneLoad) {
const materialTotal = await Material.find({organization_id: 1}).countDocuments();
const materials = await Material.find({organization_id: 1});
res.status(200).json({data: materials});
}
} catch (error) {
res.status(404).json({ message: error.message });
}
}
我曾尝试使用聚合来获得我想要的结果,但我找不到任何符合我要求的解决方案。任何帮助都会很棒,因为我对使用 mongodb 还很陌生。谢谢。
编辑(期望的结果):
Materials: [
{
_id: material1,
organization_id: 1
},
{
_id: material2,
organization_id: 1
},
{
_id: material3,
organization_id: 1
}
]
您可以在 $lookup
中使用 sub-pipeline 来执行过滤。 $addFields
稍后使用 $size
计数。
db.Sharing.aggregate([
{
"$match": {
to_id: 1
}
},
{
"$lookup": {
"from": "Material",
"let": {
to_id: "$to_id",
material_id: "$material_id"
},
"pipeline": [
{
"$match": {
$expr: {
$or: [
{
$eq: [
"$$to_id",
"$organization_id"
]
},
{
$eq: [
"$$material_id",
"$_id"
]
}
]
}
}
},
{
"$addFields": {
"organization_id": 1
}
}
],
"as": "materialLookup"
}
},
{
"$addFields": {
"materialCount": {
$size: "$materialLookup"
}
}
}
])
这里是Mongo playground供您参考。