Mongodb:对多个嵌套数组进行排序

时间:2020-06-28 11:02:24

标签: arrays mongodb sorting mongodb-query aggregation-framework

我最近开始使用mongodb(版本4.0.15),无法尝试解决以下问题。我有一组文档,其中包含许多嵌套数组。要求是使用时间戳和条件从那些数组中仅获取最新信息(元素)。我使用$ unwind,$ sort,$ group尝试了聚合框架,但无法完全弄清楚这一点。感谢您的帮助。

请考虑以下一份文件(类似地,我有成千上万份文件) 在这里,我需要列出来自memberinfo的信息(不是所有信息,而是仅某些字段),选择有效且具有最新时间戳的产品和地址(仅特定字段),如果没有数组元素将有效标志设置为true ,即使有效标志为false,也要获取具有最新时间戳的数组元素。

  {
    _id: x,
    member:
    {
      MemberInfo:
      {
        firstname: fn1,
        lastname : ln1,
        DOB: somedate
        gender: M,
        height: xx,
        weight: xx
        ….
      },
      Memberproducts: {
         MemberProduct: [
         {
           ProductName: product1,
           EffectiveDt: 1/1/2018,
           EndDt: 6/30/2018,
           Valid : true,
           description: desc1,
           ….
           ….
         },
         {
           ProductName: product2,
           EffectiveDt: 1/1/2019,
           EndDt: 12/31/2019,
           valid : true,
           description: desc2,
           ….
           ….
         },
         {
           ProductName: product3,
           EffectiveDt: 1/1/2020,
           EndDt: 12/31/9999,
           valid: false,
           description: desc3,
           …
           …
         },
        ]
      },
      MemberAddresses:
      {
        MemberAddress: [
        {
          street: address1,
          city: city1
          EffectiveDt: 1/1/2018,
          EndDt: 12/31/2019
          valid: false
           …
        },
        {
          street: address2,
          city: city2
          EffectiveDt: 1/1/2020,
          EndDt: 12/31/9999
          valid: false
          …
        } 
       ]
      }
   }
  }

以下是预期的输出:

{
    member:
    {
      MemberInfo:
      {
        firstname: fn1,
        lastname : ln1     
      },
      Memberproducts: {
         MemberProduct: [
         {
           ProductName: product2,
           EffectiveDt: 1/1/2019,
           EndDt: 12/31/2019,
           valid : true
         },
        ]
      },
      MemberAddresses:
      {
       MemberAddress: [
       {
         street: address2,
         city: city2,
         EffectiveDt: 1/1/2020
         valid: false
       }
      ]
     }
   }
 } 
 

1 个答案:

答案 0 :(得分:0)

您可以使用$let计算最近的日期,然后使用$filter仅保留EffectiveDt等于最新EffectiveDt的数组元素。请注意,如果您有多个满足条件的元素,则可能需要使用$slice仅选择一个元素

db.collection.aggregate([
  {
    $project: {
      "member.MemberInfo.firstname": true, // select firstname
      "member.MemberInfo.lastname": true, // select lastname
      "member.MemberAddresses.MemberAddress": {
        $let: {
          vars: {
            recentDate: { // set recentDate as most recent EffectiveDt
              $max: "$member.MemberAddresses.MemberAddress.EffectiveDt"
            }
          },
          in: {
            $filter: { // filter only the address with the most recent date
              input: "$member.MemberAddresses.MemberAddress",
              cond: { $eq: ["$$this.EffectiveDt", "$$recentDate"] }
            }
          }
        }
      },
      "member.Memberproducts.MemberProduct.EffectiveDt": {
        $let: {
          vars: {
            recentDate: {  // set recentDate as most recent EffectiveDt
              $max: "$member.Memberproducts.MemberProduct.EffectiveDt"
            }
          },
          in: {
            $filter: { // filter only the product with the most recent date
              input: "$member.Memberproducts.MemberProduct",
              cond: { $eq: ["$$this.EffectiveDt", "$$recentDate"] }
            }
          }
        }
      }
    }
  }
])