合并聚合并在MongoDB中查找结果

时间:2018-08-10 02:01:20

标签: node.js mongodb express mongoose aggregation-framework

我有这个模型:

private final Map<URL, Node> loadedContent = new HashMap<>();

@FXML
private void handlePanelButtonAction(ActionEvent event) {
    loadedContent.computeIfAbsent(getResource(event.getSource()), url -> {
        try {
            FXMLLoader loader = new FXMLLoader(url);
            Node result = loader.load();
            ClientContainer controller = loader.getController();
            controller.setClient(client);
            mainPane.getChildren().add(result);
            return result;
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }).toFront();
}

因此,当我发出HTTP Get请求时,会收到一系列记录:

const recordSchema = new Schema({ user: { type: Schema.ObjectId, ref: 'Person', required: true }, date: { type: Date, default: Date.now() }, time: { type: Date, default: Date.now() } });

重点是,我正在使用聚合来获取每个用户的记录数(我得到了这份封面),但是我想将其与查找结果合并以得到如下内容:

[{/*record1*/}, {/*record2*/}, ...]

那么,我怎么得到这个?

注意:我正在使用它作为某些图表的数据,应该在节点上还是在前端上处理?

2 个答案:

答案 0 :(得分:0)

您可以使用$lookup运算符按ID链接用户的原始记录

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

答案 1 :(得分:0)

这可以在后端完成,如果您在后端使用的是MongoDB Server 3.4.4或更高版本,则 $facet 聚合管道应满足您的需求。 / p>

请考虑以下示例,该示例使用 $facet 在同一聚合管道中运行两个聚合查询:一个返回今天的记录,另一个返回集合中每个用户的计数:

let start = new Date();
start.setHours(0,0,0,0);

let end = new Date();
end.setHours(23,59,59,999);

Record.aggregate([
    { '$facet': {
        'records': [
            { '$match': { 
                'date': {
                    '$gte': start,
                    '$lte': end
                }
            } }
        ],
        'stats': [
            { '$group': { 
                '_id': '$user',
                'count': { '$sum': 1 }
            } }
        ]
    } }
]).exec((err, results) => {
    if (err) {
        console.error(err);
        throw new Error(err);
    }

    const data = results[0];
    console.log(JSON.stringify(data, null, 4));
})

对于MongoDB 3.2及更低版本

1。使用承诺

const recordsQuery = Record.find({ 'date': {
    '$gte': start, // date object representing start of today
    '$lte': end    // date object representing end of today
} }).lean().exec();

const statsQuery = Record.aggregate([
    { '$group': { 
        '_id': '$user',
        'count': { '$sum': 1 }
    } }
]).exec();

Promise.all([ recordsQuery, statsQuery ]).then(([ recordsData, statsData ]) => {
    const records = recordsData[0];
    const stats = statsData[0];

    const data = { records, stats };
    console.log(JSON.stringify(data, null, 4));
}).catch(err => console.error(err));

2。使用异步/等待

(async () =>  {
    try {
        const recordsQuery = await Record.find({ 'date': {
            '$gte': start, // date object representing start of today
            '$lte': end    // date object representing end of today
        } }).lean().exec();

        const statsQuery = await Record.aggregate([
            { '$group': { 
                '_id': '$user',
                'count': { '$sum': 1 }
            } }
        ]).exec();

        const records = recordsQuery[0];
        const stats = statsQuery[0];

        const data = { records, stats };
        console.log(JSON.stringify(data, null, 4));
    } catch (err) {
        console.error(err);
    }
})();