繁体   English   中英

MongoDB - 获取文档中每个字段的每个唯一值的计数

[英]MongoDB - Get Count of each unique value for each field in document

过去两天我一直在寻找更好的解决方案,但没有想出任何办法。

基本上,我有一个包含以下文档的集合:

{ _id:5b5c92014fdd1f82c288530d
combine_id:1234
forty:4.65
broad:10.66
shuttle:4.18
threeCone:7.08
vert:40
bench:23
}

我希望能够在一个查询中获得每个字段的每个唯一值的总和。 类似于: forty: [{time: 4.4, count: 7}, {time: 4.41, count: 11}, ...]但对于文档中的所有六个字段。 我想要做的是为每个字段创建一个值的钟形曲线。

我现在的查询如下,但我必须为每个字段单独运行它,所以我认为必须有一个更好、更优雅的解决方案。

db.combine.aggregate([
{   $group: {
        _id: {forty: '$forty'},
        count: { $sum: 1 }
} } ]);

希望这是可能的,我已经提供了足够的信息。 谢谢

$facet允许您在同一组输入文档的单个阶段内创建多方面的聚合管道,因此您可以获得每个字段的计数,如下所示:

db.combine.aggregate([
    { '$facet': {
        'forty':    [{ '$group': { '_id': '$forty', 'count': { '$sum': 1 } } }],
        'broad':    [{ '$group': { '_id': '$broad', 'count': { '$sum': 1 } } }],
        'shuttle':  [{ '$group': { '_id': '$shuttle', 'count': { '$sum': 1 } } }],
        'threeCone':[{ '$group': { '_id': '$threeCone', 'count': { '$sum': 1 } } }],
        'vert':     [{ '$group': { '_id': '$vert', 'count': { '$sum': 1 } } }],
        'bench':    [{ '$group': { '_id': '$bench', 'count': { '$sum': 1 } } }]
    } }
])

要替换_id键,您需要为每个方面附加一个$project管道阶段,即

[
    { '$group': { 
        '_id': <facet_key>, 
        'count': { '$sum': 1 } 
    } },
    { '$project': {
        '_id': 0,
        'time': '$_id',
        'count': 1
    } }
]

稍微重构一下,如果这六个字段已知且固定,则可以按如下方式动态创建管道:

/* create the facet pipeline */
const getFacetPipeline = key => ([
    { '$group': { 
        '_id': '$'+key, 
        'count': { '$sum': 1 } 
    } },
    { '$project': {
        '_id': 0,
        'time': '$_id',
        'count': 1
    } }
]);

/* create the overall aggregate pipeline */
const getAggregationPipeline = keys => (
    keys.reduce((acc, key) => {
        acc['$facet'][key] = getFacetPipeline(key);
        return acc;
    }, { '$facet': {} })
);

/* get the pipeline for the six fields */
const pipeline = getAggregationPipeline([
    'forty', 
    'broad', 
    'shuttle', 
    'threeCone', 
    'vert', 
    'bench'
]);

/* run the aggregate pipeline */
db.combine.aggretate([pipeline]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM