【问题标题】:Mongodb group and push with empty arraysMongodb分组并使用空数组推送
【发布时间】:2021-05-26 21:51:48
【问题描述】:

当存在可能是 empty 的数组时,我遇到了 group 的问题。 集合可能是这样的:

{
    "_id" : "Contract_1",
    "ContactId" : "Contact_1",
    "Specifications" : [ ]
}

{
    "_id" : "Contract_2",
    "ContactId" : "Contact_2",
    "Specifications" : [ 
        {
            "Description" : "Descrizione1",
            "VehicleId" : "Vehicle_1",
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5"
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3"
                }
            ]
        }, 
        {
            "Description" : "Descrizione2",
            "VehicleId" : "Vehicle_2",
            "Customizations" : [ 
                {
                    "Description" : "Random furniture",
                    "ContactId" : "Contact_5"
                }, 
                {
                    "Description" : "Random furniture 2",
                    "ContactId" : "Contact_3"
                }
            ]
        }
    ]
}

{
    "_id" : "Contract_3",
    "ContactId" : "Contact_25",
    "Specifications" : [ 
        {
            "Description" : "Descrizione1",
            "VehicleId" : "Vehicle_1",
            "Customizations" : []
        }, 
        {
            "Description" : "Descrizione2",
            "VehicleId" : "Vehicle_2",
            "Customizations" : []
        }
    ]
}

如您所见,有时Specifications 可以为空,Customizations 也可以为空。 这是我执行的查询:

db.getCollection("Contract").aggregate([
  { "$lookup": {
    "from": "Contact",
    "localField": "ContactId",
    "foreignField": "_id",
    "as": "Contact"
  }},
  { "$unwind": {"path":"$Contact", "preserveNullAndEmptyArrays":true }},
  { "$unwind": { "path": "$Specifications", "preserveNullAndEmptyArrays":true }},
  { "$lookup": {
    "from": "Vehicle",
    "localField": "Specifications.VehicleId",
    "foreignField": "_id",
    "as": "Specifications.Vehicle"
  }},
  { "$unwind": {"path": {"$Specifications.Vehicle","preserveNullAndEmptyArrays":true} },
  { "$unwind": {"path": {"$Specifications.Customizations","preserveNullAndEmptyArrays":true} },
  { "$lookup": {
    "from": "Contact",
    "localField": "Specifications.Customizations.ContactId",
    "foreignField": "_id",
    "as": "Specifications.Customizations.Contact"
  }},
  { "$unwind": {"path": {"$Specifications.Customizations.Contact","preserveNullAndEmptyArrays":true} },
  { "$group": {
    "_id": {
      "_id": "$_id",
      "Description": "$Specifications.Description"
    },
    "ContactId": { "$first": "$ContactId" },
    "Contact": { "$first": "$Contact" },
    "Specifications": {
      "$push": "$Specifications.Customizations"
    }
  }},
  { "$group": {
    "_id": "$_id._id",
    "ContactId": { "$first": "$ContactId" },
    "Contact": { "$first": "$Contact" },
    "Specifications": {
      "$push": {
        "Description": "$_id.Description",
        "Customizations": "$Specifications"
      }
    }
  }}
])
}},
   { "$group": {
    "_id": "$_id._id",
    "ContactId": { "$first": "$ContactId" },
    "Contact": { "$first": "$Contact" },
    "Specifications": {
      "$push": {
        "Description": "$_id.Description",
        "Customizations": "$Specifications"
      }
    }
  }}
])

一旦查询执行,当它执行 2 $group 时就会产生问题,因为对于第一个查询,pushing $Specifications.Customizations 将创建一个内部包含空元素的数组。我想要的是,如果 Specifications 是一个空数组,将保持不变而不在里面添加一个空元素。

【问题讨论】:

  • 但我想保留文档,例如,如果我在展开规范时设置为 false,我会丢失文档编辑:对不起,我输入了错误的查询
  • 您需要将其保留为true 而不是假。
  • @Fanpark 是的,现在我使用我正在使用的正确查询进行了编辑。每次放松都是如此。但是在分组时,如果我将 Specifications 作为空数组,作为输出,我仍然希望它为空数组,但我得到一个内部有一个空元素的数组
  • 我认为问题是在查找中产生的,但应该在组中解决,可能带有过滤器

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

这是我可以看到嵌套数组的$unwind$group 的缺点之一。要摆脱这种情况,您需要再添加一个阶段 $addFields 以过滤掉空的嵌套数组。

在管道的末尾添加这个

{ "$addFields": {
  "Specifications": {
    "$filter": {
      "input": "$Specifications",
      "cond": { "$ne": ["$$this.Description", undefined] }
    }
  }
}}

【讨论】:

    【解决方案2】:

    对于那些仍然像我一样有同样问题并且@Ashh 的答案对他们不起作用的人(我无法弄清楚它对我不起作用的原因)。 $ifNull 而不是 $ne 对我有用,如下所示:

    { "$addFields": {
      "Specifications": {
        "$filter": {
          "input": "$Specifications",
          "cond": { "$ifNull": ["$$this.Description", false] }
        }
      }
    }}
    

    【讨论】:

      猜你喜欢
      • 2017-09-17
      • 2019-08-23
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 2013-11-20
      相关资源
      最近更新 更多