当其中一个字段位于子文档数组中时,如何从集合中获取两个字段的不同组合

How to get distinct combinations of two fields from a collection when one of the fields is in an array of subdocuments

来自代表类似于以下产品的文档组成的集合:

[
  {
    code: "0WE3A5CMY",
    name: "lorem",
    category: "voluptas",
    variants: [
      {
        color: "PapayaWhip",
        stock: 17,
        barcode: 4937310396997
      },
      {
        color: "RoyalBlue",
        stock: 13,
        barcode: 9787252504890
      },
      {
        color: "DodgerBlue",
        stock: 110,
        barcode: 97194456959791
      }
    ]
  },
  {
    code: "0WE3A5CMX",
    name: "ipsum",
    category: "temporibus",
    variants: [
      {
        color: "RoyalBlue",
        stock: 113,
        barcode: 23425202111840
      },
      {
        color: "DodgerBlue",
        stock: 10,
        barcode: 2342520211841
      }
    ]
  },
  {
    code: "0WE3A5CMZ",
    name: "dolor",
    category: "temporibus",
    variants: [
      {
        color: "MaroonRed",
        stock: 17,
        barcode: 3376911253701
      },
      {
        color: "RoyalBlue",
        stock: 12,
        barcode: 3376911253702
      },
      {
        color: "DodgerBlue",
        stock: 4,
        barcode: 3376911253703
      }
    ]
  }
]

我想检索 variants.colorcategory 的不同组合。所以结果应该是:

[
    {
        category: 'voluptas',
        color: 'PapayaWhip',
    },
    {
        category: 'voluptas',
        color: 'RoyalBlue',
    },
    {
        category: 'voluptas',
        color: 'DodgerBlue',
    },
    {
        category: 'temporibus',
        color: 'RoyalBlue',
    },
    {
        category: 'temporibus',
        color: 'DodgerBlue',
    }
]

根据一些粗略的研究,我认为我将不得不使用聚合,但我从未使用过这些,需要一些帮助。我已经在 How to efficiently perform "distinct" with multiple keys? 尝试了解决方案 我已经尝试了jcarter在评论中提到的方法,但它并没有解决我的问题。如果我这样做:

db.products.aggregate([
  {
    $group: {
      _id: {
        "category": "$category",
        "color": "$variants.color"
      }
    }
  }
])

我得到结果:

[
  {
    "_id": {
      "category": "temporibus",
      "color": [
        "MaroonRed",
        "RoyalBlue",
        "DodgerBlue"
      ]
    }
  },
  {
    "_id": {
      "category": "temporibus",
      "color": [
        "RoyalBlue",
        "DodgerBlue"
      ]
    }
  },
  {
    "_id": {
      "category": "voluptas",
      "color": [
        "PapayaWhip",
        "RoyalBlue",
        "DodgerBlue"
      ]
    }
  }
]

这不是我需要的。

由于 variants 是一个数组,您需要展开它并在两个字段上分组以获得基于 category + 'variants.color' 组合的独特文档。

小组赛结果如下:

[
  {
    "_id": {
      "category": "voluptas",
      "color": "DodgerBlue"
    }
  },
  {
    "_id": {
      "category": "voluptas",
      "color": "PapayaWhip"
    }
  }
]

然后使用 $replaceRoot 阶段,您可以将 _id 对象字段作为每个文档的根,以获得所需的结果。

查询:

db.collection.aggregate([
    {
      $unwind: "$variants"
    },
    {
      $group: { _id: { "category": "$category", "color": "$variants.color" } }
    },
    {
      $replaceRoot: { newRoot: "$_id" }
    }
  ])

测试: mongoplayground