node.js - NodeJS、MongoDB - 从 GET 请求中的聚合返回 JSON 响应

标签 node.js mongodb aggregate response middleware

我创建了一个聚合管道,它从数据库返回许多文档。我还可以使用“console.log”查看结果。但是当我使用 Postman 时,我无法在响应中返回结果。您可以测试它在 PostMan 上使用 AreaName=Hungary,Resolution=PT15M,Year=2018,Month=1,Day=1



var express = require('express');
var router = express.Router();
var assert = require('assert')
const URL = 'mongodb+srv://user:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="423731273002212e3731362730726f72323531316c2f2d2c252d26206c2c2736" rel="noreferrer noopener nofollow">[email protected]</a>/test?retryWrites=true&w=majority'
const MongoClient = require('mongodb').MongoClient
//const CircularJSON = require('circular-json');
//const {parse, stringify} = require('flatted/cjs');



router.get('/:AreaName/:Resolution/:Year/:Month/:Day', (req, res, next) => {
  const _AreaName=req.params.AreaName
  const _Resolution=req.params.Resolution
  const _Year = parseInt(req.params.Year)
  const _Month = parseInt(req.params.Month)
  const _Day = parseInt(req.params.Day)

  MongoClient.connect(URL,{
    useNewUrlParser: true,
    useUnifiedTopology: true}, 
    async (err, client) => {
      if (err) throw err; 
      else console.log('connected to db');
      assert.equal(null, err) 
      const db = client.db('energy')
      var collection = db.collection('ActualTotalLoad')
      const agg = [
        { 
          $match : 
          {
            AreaName: _AreaName,
            Day : _Day,
            Month: _Month,
            Year: _Year
          }
      },
        
        {
          $lookup:
          {
            from: 'ResolutionCode',
            localField: 'ResolutionCodeId',
            foreignField : 'Id',
            as: "resolution_codes"
          }
        },
        {
          $unwind: {path : "$resolution_codes"}
        },

        { 
          $match : {'resolution_codes.ResolutionCodeText' : _Resolution}
        },
        {
          $addFields : {ResolutionCode : '$resolution_codes.ResolutionCodeText',
                        Source :'entso-e',
                        Dataset :'ActualTotalLoad'
        }
        },

        {
          $project : 
          {
            _id:0,
            Id : 1,
            ResolutionCodeId:1,
            Source : 1,
            AreaName: 1,
            Year : 1,
            Month : 1,
            Day : 1,
            ResolutionCode : 1
          }
        }  
      ];
      var cursor = collection.aggregate(agg)
      cursor.forEach(doc => {
        console.log(doc)
      })
    
      
     await cursor.toArray((error, result) => {
        if(error) {
            return res.status(500).send(error);
        }
        cursor.forEach(doc => {
            res.send(doc)
          })

    });

  })// connection ends here
})
module.exports = router;

-> 上面的代码返回一个 json,然后服务器崩溃

我可以看到结果 "cursor.forEach(doc => { console.log(doc)}) " 在终端中,这似乎工作正常。我要问的是如何以 json 返回响应。像“res.json(cursor) ” 我尝试了一些不同的函数/方法来做但这似乎不起作用。

更新 回答后我尝试了这个

cursor.toArray((error, result) => {
        if(error) {
            return res.status(500).send(error);
        }
        cursor.forEach(doc => {
            res.send(doc)
          })
    
    });

上面的代码用Postman测试时从数据库返回1个json文档。问题是它只返回一个,然后服务器崩溃了。我要返回的文档是多个。错误消息为错误[ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置 header

最佳答案

您需要调用.toArray()方法返回所有结果。

编辑:调试代码。将 Route 更改为 App

var express = require('express');
var app = express();

var router = express.Router();
var assert = require('assert')
const URL = 'mongodb+srv://user:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e1b1d0b1c2e0d021b1d1a0b1c5e435e1e191d1d4003010009010a0c40000b1a" rel="noreferrer noopener nofollow">[email protected]</a>/test?retryWrites=true&w=majority'
const MongoClient = require('mongodb').MongoClient
//const CircularJSON = require('circular-json');
//const {parse, stringify} = require('flatted/cjs');

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.get('/:AreaName/:Resolution/:Year/:Month/:Day', (req, res) => {
  const _AreaName=req.params.AreaName
  const _Resolution=req.params.Resolution
  const _Year = parseInt(req.params.Year)
  const _Month = parseInt(req.params.Month)
  const _Day = parseInt(req.params.Day)

  MongoClient.connect(URL,{
    useNewUrlParser: true,
    useUnifiedTopology: true}, 
    async (err, client) => {
      if (err) throw err; 
      else console.log('connected to db');
      assert.equal(null, err) 
      const db = client.db('energy')
      var collection = db.collection('ActualTotalLoad')
      const agg = [
        { 
          $match : 
          {
            AreaName: _AreaName,
            Day : _Day,
            Month: _Month,
            Year: _Year
          }
      },

        {
          $lookup:
          {
            from: 'ResolutionCode',
            localField: 'ResolutionCodeId',
            foreignField : 'Id',
            as: "resolution_codes"
          }
        },
        {
          $unwind: {path : "$resolution_codes"}
        },

        { 
          $match : {'resolution_codes.ResolutionCodeText' : _Resolution}
        },
        {
          $addFields : {ResolutionCode : '$resolution_codes.ResolutionCodeText',
                        Source :'entso-e',
                        Dataset :'ActualTotalLoad'
        }
        },

        {
          $project : 
          {
            _id:0,
            Id : 1,
            ResolutionCodeId:1,
            Source : 1,
            AreaName: 1,
            Year : 1,
            Month : 1,
            Day : 1,
            ResolutionCode : 1
          }
        }  
      ];
      var cursor = collection.aggregate(agg)

      await cursor.toArray((error, result) => {
        if(error) {
            return res.status(500).send(error);
        }
        res.send(result);
    });

  })// connection ends here
})
module.exports = router;

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

结果: Result

关于node.js - NodeJS、MongoDB - 从 GET 请求中的聚合返回 JSON 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59617836/

相关文章:

javascript - kafka-node 有没有办法在崩溃后请求收到的消息?

javascript - react : How to make pagination in Loopback

node.js - 获取一个集合并为响应添加一个值

javascript - 如何使用 javascript 在 mongodb 中引发自定义错误

r - 在多个不同的切片上应用聚合函数

r - 无法让aggregate()按组进行回归工作

javascript - 以同步方式调用 Facebook Messenger API

mongodb - 复制/克隆 Mongoose 文档实例的最简单方法?

django - sshtunnel.BaseSSHTunnelForwarder 无法与 SSH 网关建立 session

r - 使用聚合将多个函数应用于数据框中的每一列