19

这是我的 MongoDB 集合:

{
    "_id" : ObjectId("515d8f53175b8ecb053425c2"),
    "category" : "Batteries",
    "products" : [
        {
            "brand" : "Duracell",
            "item" : [
                "AA",
                "AAA"
            ]
        },
        {
            "brand" : "Everyday",
            "item" : [
                "9V",
                "AA",
                "12V"
            ]
        }
    ]
}

我需要的输出是

1)所有项目的唯一列表

{["AA", "AAA", "9V", "12V"]}

和 2. 每个产品的唯一项目列表

{
    "category" : "Batteries",
    "item": ["AA", "AAA", "9V", "12V"]
}

我对 MongoDB 很陌生,我尝试了不同的聚合函数,但似乎没有任何效果。请帮忙。

4

4 回答 4

28

经过几次尝试,我已经解决了这个问题。这是命令:

db.xyz.aggregate( {$project: {a: '$products.item'}}, 
    {$unwind: '$a'}, 
    {$unwind: '$a'}, 
    {$group: {_id: 'a', items: {$addToSet: '$a'}}});

db.xyz.aggregate( {$project: {category: 1, a: '$products.item'}}, 
    {$unwind: '$a'}, 
    {$unwind: '$a'}, 
    {$group: {_id: '$category', items: {$addToSet: '$a'}}});
于 2013-04-04T23:32:17.230 回答
6

mongodb3.4之后有了$reduceoperator,所以我们可以扁平化一个数组,不需要额外的stage。

1.

col.aggregate([
  {
    $project: {
      items: {
        $reduce: {
          input: "$products.items",
          initialValue: [],
          in: { $concatArrays: ["$$value", "$$this"] },
        },
      },
    },
  },
  { $unwind: "$items" },
  { $group: { _id: null, items: { $addToSet: "$items" } } },
]);

2.

col.aggregate([
  {
    $project: {
      category: 1,
      items: {
        $setUnion: {
          $reduce: {
            input: "$products.items",
            initialValue: [],
            in: { $concatArrays: ["$$value", "$$this"] },
          },
        },
      },
    },
  },
]);
于 2020-05-12T03:40:14.567 回答
1

我知道这是一个老问题,几年前你已经解决了!但是您标记为正确的答案存在一个小问题,它可能不适合所有情况。这$unwind是一个昂贵的运算符,可能会影响大型数据集的延迟和内存消耗。我认为$reduce运营商在这种情况下表现更好。

于 2020-08-03T12:06:32.480 回答
0

我不确定你们在聚合函数中都尝试过什么,但我认为 unwind 会帮助你做同样的事情,假设你无法完成它,我们有一个 map-reduce 可以让你轻松做到这一点一 。您可以查看http://docs.mongodb.org/manual/applications/map-reduce/。它允许您以您想要的方式获取数据,并且您可以轻松获取列表。我认为标签列上的 $unwind 然后 $group 它们将始终按照您在 1 中的要求为我们提供不同标签的列表,对于第二种情况,在两个关键类别和项目上创建 $group 之前是 $unwind 。

于 2013-04-04T14:57:32.167 回答