Mongo聚合查询构面导航

时间:2016-01-18 23:33:10

标签: mongodb aggregation-framework

我有一个集合products,其中包含这样的文档(产品)(仅限相关代码):

{ "_id": "prod1", ... "colors": ["red","blue"], "size": ["S", "M"], ...}
{ "_id": "prod2", ... "colors": ["red","green"], "size": ["S", "XL"], ...}
{ "_id": "prod3", ... "colors": ["yellow","blue"], "size": ["XL", "XXL"], ...}

我想仅向用户提供可用选项,作为分面搜索,例如选项名称和可用选项数量。

颜色

red 2
blue 2
green 1
yellow 1

尺寸:

S 2
M 1
XL 2
XXL 1

如果我必须在SQL中执行此操作,我可能必须为每个构面组运行查询。

SELECT colors, count(*) AS number FROM products GROUP BY colors

比第二个查询

SELECT size, count(*) AS number FROM test GROUP BY sizes

如果有人选择颜色“红色”,那么我可能不得不在每个查询中添加“WHERE”子句:

WHERE colors = 'red'

有人比我更有经验,在MongoDB中帮助我这个例子吗?我是否必须运行两个查询或者是否存在我缺少的内容并且可以在一个查询中完成?我想我会有很多产品。任何帮助赞赏。特别是如果有任何技巧加速它。我想从一开始就把它弄好,因此提出问题。感谢。

4 个答案:

答案 0 :(得分:3)

以下是MongoDB聚合查询的解决方案。下面是我的虚拟收藏。

    {
        "_id" : ObjectId("584b82055855b8ea7ea29d65"),
        "colors" : [ 
            "Red", 
            "Yellow"
        ],
        "size" : [ 
            "S", 
            "M"
        ]
    }
    {
        "_id" : ObjectId("584b82185855b8ea7ea29d66"),
        "colors" : [ 
            "Red", 
            "Orange"
        ],
        "size" : [ 
            "S", 
            "XL"
        ]
    }
.
.

运行以下查询后。

    db.getCollection('products').aggregate([
    {$unwind : "$colors"},
    {$group : {
        _id : "$colors",
        "sum": {$sum : 1}
    }},
    {
        $project : {
            _id : 0,
            "color":"$_id",
            "count":"$sum"
        }
    }
])

然后输出是:

{
    "color" : "Green",
    "count" : 2
}
{
    "color" : "Orange",
    "count" : 1
}
{
    "color" : "Yellow",
    "count" : 2
}
{
    "color" : "Red",
    "count" : 2
}

如果您只想查找红色颜色的总和,请在此

下查询
db.getCollection('products').aggregate([
    {$unwind : "$colors"},
    {$match : {"colors":"Red"}},
    {$group : {
        _id : "$colors",
        "sum": {$sum : 1}
    }},
    {
        $project : {
            _id : 0,
            "color":"$_id",
            "count":"$sum"
        }
    }
])

以上查询的输出为:

{
    "color" : "Red",
    "count" : 2
}

答案 1 :(得分:1)

$ unwind的神奇之处

当你需要将某些东西计入数组时,你必须首先解开它。看看这个:

db.products.aggregate([ { $unwind : "$colors" }] )

它为数组的每个项生成一行。

一旦你放松它,你可以管道下一组:

db.products.aggregate([ 
{ $unwind : "$colors" }, 
{$group: { _id : "$colors", total_colors : { $sum : 1} } } 
] )

根据需要命名聚合字段:)可以根据需要对大小进行分组。

答案 2 :(得分:1)

db.entry.aggregate([
{$unwind : "$size" },
{$group: { "_id" : "$size", count : { $sum : 1 } } }
]).pretty()

希望这会有所帮助,您可以根据需要自定义“计数”。 field和$ unwind定义:

从输入文档解构数组字段,为每个元素输出文档。每个输出文档都是输入文档,数组字段的值由元素替换。

https://docs.mongodb.org/manual/reference/operator/aggregation/unwind/

答案 3 :(得分:1)

分面搜索在MongoDB数据库的3.4版本中实现。

{ $facet:
   {
      <outputField1>: [ <stage1>, <stage2>, ... ],
      <outputField2>: [ <stage1>, <stage2>, ... ],
      ...

   }
}

这是link to documentation