我已经搜索了Internet和StackOverflow,但找不到答案甚至问题。
我有两个收藏集reports
和users
。我希望我的查询返回所有报告,并指示指定的用户是否将该报告作为其阵列中的收藏夹。
报告集合
{ _id: 1, name:"Report One"}
{ _id: 2, name:"Report Two"}
{ _id: 3, name:"Report Three"}
用户集合
{_id: 1, name:"Mike", favorites: [1,3]}
{_id: 2, name:"Tim", favorites: [2,3]}
用户所需的结果。name=“ Mike”
{ _id: 1, name:"Report One", favorite: true}
{ _id: 2, name:"Report Two", favorite: false}
{ _id: 3, name:"Report Three", favorite: true}
我能找到的所有答案都在本地(reports
)字段上使用$ unwind,但是在这种情况下,本地字段不是数组。外来字段是数组。
我该如何放松异地?有更好的方法吗?
我在网上看到有人建议制作另一个收藏集favorites
,其中包含:
{ _id: 1, userId: 1, reportId: 1 }
{ _id: 2, userId: 1, reportId: 3 }
{ _id: 3, userId: 2, reportId: 2 }
{ _id: 4, userId: 2, reportId: 3 }
此方法似乎应该是不必要的。加入外部数组中的ID应该很简单,对吧?
答案 0 :(得分:2)
您可以使用$lookup with custom pipeline来获得0
或1
的结果,然后使用$size将数组转换为单个布尔值:
db.reports.aggregate([
{
$lookup: {
from: "users",
let: { report_id: "$_id" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: [ "$name", "Mike" ] },
{ $in: [ "$$report_id", "$favorites" ] }
]
}
}
}
],
as: "users"
}
},
{
$project: {
_id: 1,
name: 1,
favorite: { $eq: [ { $size: "$users" }, 1 ] }
}
}
])
或者,如果您需要使用低于3.6的MongoDB版本,则可以使用常规的$lookup
,然后使用$filter仅获得name
为Mike
的那些用户:< / p>
db.reports.aggregate([
{
$lookup: {
from: "users",
localField: "_id",
foreignField: "favorites",
as: "users"
}
},
{
$project: {
_id: 1,
name: 1,
favorite: { $eq: [ { $size: { $filter: { input: "$users", as: "u", cond: { $eq: [ "$$u.name", "Mike" ] } } } }, 1 ] }
}
}
])