【问题标题】:How to filter multiple nested array object by using multi nested objects using aggregate in mongoose node js如何在猫鼬节点js中使用聚合使用多个嵌套对象来过滤多个嵌套数组对象
【发布时间】:2019-10-19 20:13:00
【问题描述】:

我需要使用 mongoose nodejs 聚合多个嵌套对象来过滤多个嵌套数组对象。我已经提到了来自集合和多过滤器对象的示例记录数据。

我使用一个电子商务产品列表视图页面。在此列表页面中,我们有许多具有不同功能的产品。在这里,我需要使用该产品功能列表过滤该产品。

示例:

我有 3 部具有不同功能的手机,例如 颜色,内存,存储。这些功能被放置在“productfilter”中 下面的样本收集记录中的数组。我可以选择多个 过滤手机的功能,例如,我选择颜色:蓝色、金色和 内存:6GB、8GB。这里来自示例产品列表数据的第二个产品,需要 根据选定的过滤器获取。因为颜色:蓝色和内存:6GB 是 与第二个产品对象中的“IsDefault:'true'”匹配 示例产品列表数据

这里需要根据过滤请求数据过滤记录,同时需要检查“isDefault”是否为“true”

样本采集记录

[
  {
    "_id": "5d710f9950b94f237f04407b",
    "productfilter": [
      {
        "_id": "5d8d29ae014da910c0de0799",
        "specTitle": "Color",
        "attributeOptions": [
          {
            "_id": "5d8d29ae014da910c0de079d",
            "specLabel": "Rose Gold",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-rose-gold-6gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de079c",
            "specLabel": "Black",
            "isDefault": "true",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-6gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de079b",
            "specLabel": "Blue",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-6gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de079a",
            "specLabel": "Red",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-red-6gb-64gb-redmi-note-6-pro"
          }
        ]
      },
      {
        "_id": "5d8d29ae014da910c0de0796",
        "specTitle": "RAM",
        "attributeOptions": [
          {
            "_id": "5d8d29ae014da910c0de0798",
            "specLabel": "4GB",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-4gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de0797",
            "specLabel": "6GB",
            "isDefault": "true",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-6gb-64gb-redmi-note-6-pro"
          }
        ]
      },
      {
        "_id": "5d8d29ae014da910c0de0794",
        "specTitle": "Storage",
        "attributeOptions": [
          {
            "_id": "5d8d29ae014da910c0de0795",
            "specLabel": "64GB",
            "isDefault": "true",
            "specContent": ""
          }
        ]
      }
    ]
  },
  {
    "_id": "5d710fe050b94f237f04407e",
    "productfilter": [
      {
        "_id": "5d8d29ae014da910c0de07a3",
        "specTitle": "Color",
        "attributeOptions": [
          {
            "_id": "5d8d29ae014da910c0de07a7",
            "specLabel": "Rose Gold",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-rose-gold-6gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de07a6",
            "specLabel": "Black",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-6gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de07a5",
            "specLabel": "Blue",
            "isDefault": "true",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-6gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de07a4",
            "specLabel": "Red",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-red-6gb-64gb-redmi-note-6-pro"
          }
        ]
      },
      {
        "_id": "5d8d29ae014da910c0de07a0",
        "specTitle": "RAM",
        "attributeOptions": [
          {
            "_id": "5d8d29ae014da910c0de07a2",
            "specLabel": "4GB",
            "isDefault": "false",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-4gb-64gb-redmi-note-6-pro"
          },
          {
            "_id": "5d8d29ae014da910c0de07a1",
            "specLabel": "6GB",
            "isDefault": "true",
            "specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-6gb-64gb-redmi-note-6-pro"
          }
        ]
      },
      {
        "_id": "5d8d29ae014da910c0de079e",
        "specTitle": "Storage",
        "attributeOptions": [
          {
            "_id": "5d8d29ae014da910c0de079f",
            "specLabel": "64GB",
            "isDefault": "true",
            "specContent": ""
          }
        ]
      }
    ]
  }
]

从产品列表视图页面中的过滤选项列表中采样选定的请求数据,以过滤上述记录

{
  "filter": {
    "genericFilter": [
      {
        "specTitle": "Color",
        "specLabel": [
          "Blue",
          "Gold",
          "Rose Gold"
        ]
      },
      {
        "specTitle": "RAM",
        "specLabel": [
          "6GB",
          "8GB"
        ]
      },
      {
        "specTitle": "Storage",
        "specLabel": [
          "64GB",
          "256GB"
        ]
      }
    ]
  }
}

【问题讨论】:

  • 嗨@uday-s 这不是很清楚。提供更好的描述
  • 我已经更新了详细描述。你能检查一下吗

标签: node.js mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

这可以使用Aggregation Pipeline 来完成,如下所示

db.products.aggregate([
   {
        $unwind: "$productfilter"
   },
   {
        $unwind: "$productfilter.attributeOptions"
   },
   {
       $project: {
           "specTitle": "$productfilter.specTitle",
           "specLabel": "$productfilter.attributeOptions.specLabel",
           "isDefault": "$productfilter.attributeOptions.isDefault",
           _id:0
       }
   },
   {
       $group: {
           "_id": "$specTitle",
           "specLabel": {$addToSet: "$specLabel"}
       }
   },
   {
    $project: {
        "specTitle": "$_id",
        "specLabel": "$specLabel",
        "isDefault": "$productfilter.attributeOptions.isDefault",
        _id:0
    }
   },
])

说明:

  1. 在第一阶段,查询unwinds数组productFilter;这意味着为productFilter数组项的每个值将文档分成多条记录
  2. 在第二阶段,它对 attributeOptions 执行相同的操作,它位于 productFilter 内部
  3. Project 阶段,保留文档中的相关字段并为其命名以供以后使用
  4. Groups 所有文档现在由specTitle 创建并创建一个新字段“specLabel”(它利用$addToSet 从所有不同的“specLabel”值创建一个数组。)。由于它是一个集合,因此它不会重复存在的值。
  5. 最终根据需要重新构建文档。 (这里我没有根据示例结果包含过滤器和 genericFilter,因为它们是多余的,但如果您愿意,您可以编辑最后一个阶段 $project 以满足您的需求

【讨论】:

  • @uday-s 这是否为您解决了问题?如果此答案可以帮助您解决问题,请点赞。如果问题的正确答案,则接受答案。
猜你喜欢
  • 2020-05-10
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 2020-10-28
  • 1970-01-01
  • 2020-06-12
相关资源
最近更新 更多