是否可以根据 mongo 文档中的条件对内部数组进行 $lookup
Is it possible to do $lookup with an internal array based on a condition within a mongo document
我有 clientSubscription 列表,每个 clientSubscriptions 都有一个数组 subscription.The activeSubNo 表示哪个订阅有效,comcomingSubNo 表示 upcoming/next 订阅。
{
"clientNo" : 3,
"activeSubNo" : 2,
"upcomingSubNo" : 3,
"subscriptions" : [
{
"subNo" : 1, "Type" : "FREE", "startDate" : ISODate("2021-09-02"),"endDate" : ISODate("2021-11-02")
},
{
"subNo" : 2, "Type" : "PAID", "startDate" : ISODate("2021-12-02"), "endDate" : ISODate("2022-02-04")
}
,
{
"subNo" : 3, "Type" : "PAID", "startDate" : ISODate("2022-02-05"), "endDate" : ISODate("2022-05-04")
} ]
}
{
"clientNo" : 5,
"activeSubNo" : 2,
"upcomingSubNo" : 0,
"subscriptions" : [
{
"subNo" : 1, "Type" : "FREE", "startDate" : ISODate("2021-09-02"),"endDate" : ISODate("2021-11-02")
},
{
"subNo" : 2, "Type" : "PAID", "startDate" : ISODate("2021-12-02"), "endDate" : ISODate("2022-02-03")
}]
}
{
"clientNo" : 6,
"activeSubNo" : 1,
"upcomingSubNo" : 0,
"subscriptions" : [
{
"subNo" : 1, "Type" : "FREE", "startDate" : ISODate("2022-01-01"),"endDate" : ISODate("2022-02-28")
}
]
}
我需要构建一个视图,该视图根据最早到期的客户端订阅进行排序。因此,endDate 的比较只需要在每条记录之间的 activeSubscription 日期之间进行。如果 comcomingSubNo 值为 0,则视图应指示未购买新订阅。
查看
Client Active-SubNo Type StartDate EndDate Upcoming-SubNo Type StartDate EndDate
5 2 PAID 2021-12-02 2022-02-03 -
3 2 PAID 2021-12-02 2022-02-04 3 PAID 2022-02-05 2022-05-04
6 1 FREE 2022-01-01 2022-02-28 -
是否可以使用像这样的单个集合和聚合查询来执行此操作?
或者我是否必须将其分成 2 个集合(将订阅作为一个单独的集合),以便我可以进行查找?
也许是这个:
db.collection.aggregate([
{
$set: {
startDate: { $arrayElemAt: [ "$subscriptions.startDate", { $subtract: [ "$activeSubNo", 1 ] } ] },
endDate: { $arrayElemAt: [ "$subscriptions.endDate", { $subtract: [ "$activeSubNo", 1 ] } ] },
Type: { $arrayElemAt: [ "$subscriptions.Type", { $subtract: [ "$activeSubNo", 1 ] } ] },
subscriptions: {
$cond: {
if: { $eq: [ "$upcomingSubNo", 0 ] },
then: "$$REMOVE",
else: { $arrayElemAt: [ "$subscriptions", { $subtract: [ "$upcomingSubNo", 1 ] } ] }
}
}
}
}
])
这些文档似乎是从包含在自身中的数组字段中自引用的,即 subscriptions
。我假设 subNo
保证是唯一的 & auto-incremented 确保相同 subNo
上没有 2 subscriptions
元素冲突。我相信这里直观的事情仍然是 equality-check 而不是进行 $subtract
算术以落在正确的索引上。我建议你这样做:
db.collection.aggregate([
{
"$addFields": {
"activeSubscription": {
"$first": {
"$filter": {
"input": "$subscriptions",
"as": "s",
"cond": {
$eq: [
"$$s.subNo",
"$activeSubNo"
]
}
}
}
}
}
},
])
我有 clientSubscription 列表,每个 clientSubscriptions 都有一个数组 subscription.The activeSubNo 表示哪个订阅有效,comcomingSubNo 表示 upcoming/next 订阅。
{
"clientNo" : 3,
"activeSubNo" : 2,
"upcomingSubNo" : 3,
"subscriptions" : [
{
"subNo" : 1, "Type" : "FREE", "startDate" : ISODate("2021-09-02"),"endDate" : ISODate("2021-11-02")
},
{
"subNo" : 2, "Type" : "PAID", "startDate" : ISODate("2021-12-02"), "endDate" : ISODate("2022-02-04")
}
,
{
"subNo" : 3, "Type" : "PAID", "startDate" : ISODate("2022-02-05"), "endDate" : ISODate("2022-05-04")
} ]
}
{
"clientNo" : 5,
"activeSubNo" : 2,
"upcomingSubNo" : 0,
"subscriptions" : [
{
"subNo" : 1, "Type" : "FREE", "startDate" : ISODate("2021-09-02"),"endDate" : ISODate("2021-11-02")
},
{
"subNo" : 2, "Type" : "PAID", "startDate" : ISODate("2021-12-02"), "endDate" : ISODate("2022-02-03")
}]
}
{
"clientNo" : 6,
"activeSubNo" : 1,
"upcomingSubNo" : 0,
"subscriptions" : [
{
"subNo" : 1, "Type" : "FREE", "startDate" : ISODate("2022-01-01"),"endDate" : ISODate("2022-02-28")
}
]
}
我需要构建一个视图,该视图根据最早到期的客户端订阅进行排序。因此,endDate 的比较只需要在每条记录之间的 activeSubscription 日期之间进行。如果 comcomingSubNo 值为 0,则视图应指示未购买新订阅。
查看
Client Active-SubNo Type StartDate EndDate Upcoming-SubNo Type StartDate EndDate
5 2 PAID 2021-12-02 2022-02-03 -
3 2 PAID 2021-12-02 2022-02-04 3 PAID 2022-02-05 2022-05-04
6 1 FREE 2022-01-01 2022-02-28 -
是否可以使用像这样的单个集合和聚合查询来执行此操作? 或者我是否必须将其分成 2 个集合(将订阅作为一个单独的集合),以便我可以进行查找?
也许是这个:
db.collection.aggregate([
{
$set: {
startDate: { $arrayElemAt: [ "$subscriptions.startDate", { $subtract: [ "$activeSubNo", 1 ] } ] },
endDate: { $arrayElemAt: [ "$subscriptions.endDate", { $subtract: [ "$activeSubNo", 1 ] } ] },
Type: { $arrayElemAt: [ "$subscriptions.Type", { $subtract: [ "$activeSubNo", 1 ] } ] },
subscriptions: {
$cond: {
if: { $eq: [ "$upcomingSubNo", 0 ] },
then: "$$REMOVE",
else: { $arrayElemAt: [ "$subscriptions", { $subtract: [ "$upcomingSubNo", 1 ] } ] }
}
}
}
}
])
这些文档似乎是从包含在自身中的数组字段中自引用的,即 subscriptions
。我假设 subNo
保证是唯一的 & auto-incremented 确保相同 subNo
上没有 2 subscriptions
元素冲突。我相信这里直观的事情仍然是 equality-check 而不是进行 $subtract
算术以落在正确的索引上。我建议你这样做:
db.collection.aggregate([
{
"$addFields": {
"activeSubscription": {
"$first": {
"$filter": {
"input": "$subscriptions",
"as": "s",
"cond": {
$eq: [
"$$s.subNo",
"$activeSubNo"
]
}
}
}
}
}
},
])