2017-07-18 99 views
0

我得到'排序超過內存限制...'錯誤,它指示在我的聚合中使用allowDiskUse(true)。我的問題是,我無法弄清楚在哪裏添加到我的代碼。我曾嘗試將它作爲管道中的對象添加,並作爲aggregate()方法調用中的一個屬性添加,並在運行時遇到錯誤。Add AllowDiskUse(true)to aggregation

代碼如下:

server.get('/cheap-flight-by-route', function (req, res, next) { 

    Flights.aggregate(
     {$sort: {'fare.total_price': 1}}, 
     {$lookup: { 
      from: 'travelroutes', 
      localField: 'route', 
      foreignField: '_id', 
      as: 'routes' 
     }}, 
     {$match: { 
      'routes._id': {$exists: true} 
     }}, 
     {$group: { 
       _id: { 
        departureAirport: '$routes.departureAirport', 
        arrivalAirport: '$routes.arrivalAirport', 
       }, 
       total_price: {$min: '$fare.total_price'}, 
       avg_price: {$avg: '$fare.total_price'}, 
       created: {$first: '$created'}, 
       doc: {$first: '$$ROOT'} 
      } 
     }, 
     {$project: { 
      departureAirport: {$arrayElemAt: ['$_id.departureAirport', 0]}, 
      arrivalAirport: {$arrayElemAt: ['$_id.arrivalAirport', 0]}, 
      created : '$created', 
      price: '$total_price', 
      averagePrice: '$avg_price', 
      'doc': 1, 
      '_id': 0 
     }}, 
     {$sort: { 
      'created': 1, 
      'departureAirport': 1, 
      'arrivalAirport': 1 
      }, 
     }, 
     function(err, cheapFlights){ 
      if (err) { 
       log.error(err) 
       return next(new errors.InvalidContentError(err.errors.name.message)) 
      } 
      res.send(cheapFlights) 
      next() 
     } 
    ) // <-- if I add a .allowDiskUse(true) here it throws a 'bad property' error 
}) 

回答

0

我使你的代碼的一些變化,試試這個:

server.get('/cheap-flight-by-route', function (req, res, next) { 
    Flights.aggregate([ 
     {$sort: { 
      'fare.total_price': 1 
     } }, 
     {$lookup: { 
      from: 'travelroutes', 
      localField: 'route', 
      foreignField: '_id', 
      as: 'routes' 
     } }, 
     {$match: { 
      'routes._id': {$exists: true} 
     } }, 
     {$group: { 
      _id: { 
       departureAirport: '$routes.departureAirport', 
       arrivalAirport: '$routes.arrivalAirport', 
      }, 
      total_price: {$min: '$fare.total_price'}, 
      avg_price: {$avg: '$fare.total_price'}, 
      created: {$first: '$created'}, 
      doc: {$first: '$$ROOT'} 
     } }, 
     {$project: { 
      departureAirport: {$arrayElemAt: ['$_id.departureAirport', 0]}, 
      arrivalAirport: {$arrayElemAt: ['$_id.arrivalAirport', 0]}, 
      created : '$created', 
      price: '$total_price', 
      averagePrice: '$avg_price', 
      'doc': 1, 
      '_id': 0 
     } }, 
     {$sort: { 
      'created': 1, 
      'departureAirport': 1, 
      'arrivalAirport': 1 
     } } 
    ], 
    { 
     allowDiskUse: true 
    }, 
    function (err, cheapFlights) { 
     if (err) { 
      log.error(err); 
      return next(new errors.InvalidContentError(err.errors.name.message)); 
     } 
     res.send(cheapFlights); 
     next(); 
    }); 
}); 

或者你可以嘗試管道:

const JSONStream = require('JSONStream'); 
server.get('/cheap-flight-by-route', function (req, res) { 
    let stream = Flights.aggregate([ 
     {$sort: { 
      'fare.total_price': 1 
     } }, 
     {$lookup: { 
      from: 'travelroutes', 
      localField: 'route', 
      foreignField: '_id', 
      as: 'routes' 
     } }, 
     {$match: { 
      'routes._id': {$exists: true} 
     } }, 
     {$group: { 
      _id: { 
       departureAirport: '$routes.departureAirport', 
       arrivalAirport: '$routes.arrivalAirport', 
      }, 
      total_price: {$min: '$fare.total_price'}, 
      avg_price: {$avg: '$fare.total_price'}, 
      created: {$first: '$created'}, 
      doc: {$first: '$$ROOT'} 
     } }, 
     {$project: { 
      departureAirport: {$arrayElemAt: ['$_id.departureAirport', 0]}, 
      arrivalAirport: {$arrayElemAt: ['$_id.arrivalAirport', 0]}, 
      created : '$created', 
      price: '$total_price', 
      averagePrice: '$avg_price', 
      'doc': 1, 
      '_id': 0 
     } }, 
     {$sort: { 
      'created': 1, 
      'departureAirport': 1, 
      'arrivalAirport': 1 
     } } 
    ]) 
    .cursor() 
    .exec(); 

    res.set('Content-Type', 'application/json'); 
    stream.pipe(JSONStream.stringify()).pipe(res); 
}); 
+0

謝謝尤里,管道的例子工作時,我補充說: .allowDiskUse(true)之前的.cursor() - 我想你只是忘了補充說。感謝您的幫助! – slippedon

0

試試你的功能添加之後,作爲第二聚集參數。

` 
    function(err, cheapFlights){ 
     if (err) { 
      log.error(err) 
      return next(new errors.InvalidContentError(err.errors.name.message)); 
     } 
     res.send(cheapFlights); 
     next(); 
    }, 
    { allowDiskUse: true } 
) 
` 
+0

我試了一下你的建議,它給了我下面的錯誤: 「參數必須是聚合管道操作員」 – slippedon

+0

是否有更多的標準或更易於管理的方式來編寫此內容,以便我可以將其用於較大的數據集? – slippedon