【问题标题】:MongoDB select distinct and countMongoDB选择不同的并计数
【发布时间】:2015-04-23 06:39:01
【问题描述】:

我有一个看起来像这样的产品集合:

products = [
  {
      "ref": "1",
      "facets": [
        { 
          "type":"category",
          "val":"kitchen" 
        },
        { 
          "type":"category",
          "val":"bedroom" 
        },
        { 
          "type":"material",
          "val":"wood" 
        }            

      ]
  },
  {
      "ref": "2",
      "facets": [
        { 
          "type":"category",
          "val":"kitchen" 
        },
        { 
          "type":"category",
          "val":"livingroom" 
        },
        { 
          "type":"material",
          "val":"plastic" 
        }            
      ]
  }
]

我想选择并计算不同的类别以及具有该类别的产品数量(请注意,一个产品可以有多个类别)。类似的东西:

[
  {
    "category": "kitchen",
    "numberOfProducts": 2
  },
  {
    "category": "bedroom",
    "numberOfProducts": 1
  },
  {
    "category": "livingroom",
    "numberOfProducts": 1
  }
]

如果我能为每种不同的构面类型获得相同的结果会更好,就像这样:

[
  {
    "facetType": "category",
    "distinctValues":
          [
            {
              "val": "kitchen",
              "numberOfProducts": 2
            },
            {
              "val": "livingroom",
              "numberOfProducts": 1
            },
            {
              "val": "bedroom",
              "numberOfProducts": 1
            }
          ]
  },
  {
    "facetType": "material",
    "distinctValues":
          [
            {
              "val": "wood",
              "numberOfProducts": 1
            },
            {
              "val": "plastic",
              "numberOfProducts": 1
            }
          ]
  }
]    

我正在使用 distinct、aggregate 和 mapReduce 进行测试。但达不到需要的结果。谁能告诉我好方法吗?

更新:

使用聚合,这给了我产品具有的不同方面类别,但不是值,也不是不同值的计数:

db.products.aggregate([
    {$match:{'content.facets.type':'category'}}, 
    {$group:{ _id: '$content.facets.type'} }  
]).pretty();

【问题讨论】:

  • 向我们展示您使用 distinct、aggregated 和 mapReduce 进行的测试。

标签: mongodb


【解决方案1】:

以下聚合管道将为您提供所需的结果。在第一个管道步骤中,您需要对 facets 数组执行 $unwind 操作,以便将其解构以输出每个元素的文档。在$unwind 阶段之后是$group 操作中的第一个,它按类别和类型对来自前一个流的文档进行分组,并使用$sum 计算每组中的产品数量。下一个管道阶段中的下一个 $group 操作然后使用 $addToSet 运算符创建包含聚合值的数组。最后的管道阶段是 $project 操作,然后通过修改现有字段来转换流中的文档:

var pipeline = [
    { "$unwind": "$facets" },
    {
        "$group": {
            "_id": {
                "facetType": "$facets.type",
                "value": "$facets.val"
            },
            "count": { "$sum": 1 }
        }
    },
    {
        "$group": {
            "_id": "$_id.facetType",
            "distinctValues": {
                "$addToSet": {
                    "val": "$_id.value",
                    "numberOfProducts": "$count"
                }
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "facetType": "$_id",
            "distinctValues": 1
        }
    }
];

db.product.aggregate(pipeline);

输出

/* 0 */
{
    "result" : [ 
        {
            "distinctValues" : [ 
                {
                    "val" : "kitchen",
                    "numberOfProducts" : 2
                }, 
                {
                    "val" : "bedroom",
                    "numberOfProducts" : 1
                }, 
                {
                    "val" : "livingroom",
                    "numberOfProducts" : 1
                }
            ],
            "facetType" : "category"
        }, 
        {
            "distinctValues" : [ 
                {
                    "val" : "wood",
                    "numberOfProducts" : 1
                }, 
                {
                    "val" : "plastic",
                    "numberOfProducts" : 1
                }
            ],
            "facetType" : "material"
        }
    ],
    "ok" : 1
}

【讨论】:

  • 太好了,谢谢!让我用真实的数据库试试,我会试着理解管道......
猜你喜欢
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 2013-11-11
相关资源
最近更新 更多