是否可以根据 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 ] } ] }
        }
      }
    }
  }
])

Mongo Playground

这些文档似乎是从包含在自身中的数组字段中自引用的,即 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"
             ]
           }
         }
       }
     }
   }
 },
])

Mongo playground