2016-08-14 9 views
3

Hapiを介してMongoDBクエリ応答をクライアントにストリーミングする最良の方法は何ですか?私はhttpやリクエストでいくつかの例を見てきましたが、hapiではありません。MongoDBからHapi経由でクライアントにストリーミング応答

問題は、クライアント側でJSONオブジェクトを連結して文字列化していますが、JSONが有効なJSONではないため、JSON.parseを呼び出すことができません。

私が見た解決策のいくつかは、クライアントに送信する前にサーバー側で連結することを推奨していますが、これはストリームの価値を犠牲にしているようです。例えば

は:

"{" _id ":" 57b0b99d681bb97a9321f03e " "":1、 "B":1} {" _ ID

const Hapi = require('hapi'), 
    MongoClient = require('mongodb').MongoClient, 
    Readable = require('stream').Readable; 

// Connection url 
const url = 'mongodb://localhost:27017/test'; 

// Create a server with a host and port 
const server = new Hapi.Server(); 
server.connection({ 
    host: 'localhost', 
    port: 8000 
}); 

// Add the route 
server.route({ 
    method: 'GET', 
    path: '/stream', 
    handler: function (request, reply) { 

    let docs = [{ a: 1, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 3 }, { a: 4, b: 4 }]; 

    // Connect using MongoClient 
    MongoClient.connect(url, (err, db) => { 
     // Create a collection we want to drop later 
     const col = db.collection('stream_example'); 

     // Insert documents into collection 
     col.insertMany(docs, { w: 1 }, function (err) { 
     if (err) return console.log(err); 

     // Peform a find to get a cursor 
     const stream = col.find() 
      .stream({ 
      transform: function (doc) { 
       return JSON.stringify(doc); 
      } 
      }); 

     reply(new Readable().wrap(stream)); 
     }); 
    }); 
    } 
}); 

// Start the server 
server.start(err => { 
    if (err) { 
    throw err; 
    } 
    console.log('Server running at:', server.info.uri); 
}); 

はresponse.resultを返します":" 57b0b99d681bb97a9321f03f "、" a ":2、" b ":2} {" _id ":" 57b0b99d681bb97a9321f040 "、" a ":3、" b ":3} {" _id ":" 57b0b99d681bb97a9321f041 "、" a ":4、" b ":4}"

有効なJSONではないため、解析できません。

イベントストリームモジュールの.join( '\ n')ストリームにこのストリームをパイプして改行を追加しようとしましたが、文字列化されたJSONを作成する前後にstring'd [["と"] "配列ですが、まだ成功していません。とにかくこれはあまりにもハッキリと感じます。

良い方法がありますか?

答えて

-1

ここでは、HapiでMongoをどのように使用していたかの例を示します。ハピハンドラ(BoardHandler.js)で

module.exports = {  
    GetAllBoards: function (facility) { 
     return new Promise(function (resolve, reject) { 
      var db = mongo.ETestDatabase; 
      db.collection('boards').find({ "Location.Facility": facility }).toArray().then(r => { 
       resolve(r); 
      }).catch(err => { 
       logger.error('Error getting all boards by facility - ' + err.message); 
       reject(err.message); 
      }); 
     }); 
    } 
}; 

:BoardRepo.jsから

module.exports = {  
    GetAllBoards: { 
     method: 'GET', 
     path: '/v1/boards/facility/all/{facility}', 
     config: { 
      auth: 'jwt', 
      plugins: { 'hapiAuthorization': { roles: ['ADMINISTRATOR', 'MANAGER', 'TECHNICIAN', 'OPERATOR'] } }, 
      description: 'Gets all boards per facility', 
      tags: ['api'], 
      handler: (request, reply) => { 
       logger.info('[' + request.auth.credentials.username + '] GetAllBoards requested'); 
       var facility = request.params.facility; 
       repo.GetAllBoards(facility) 
        .then(boards => { 
         if (boards !== null) { 
          reply(boards); 
         } else { 
          reply().code(404); 
         } 
        }) 
        .catch(err => { 
         geh.HandleError(request.auth.credentials.username, err, reply); 
        }); 
      } 
     } 
    } 
}; 
+1

しかし、このアプローチは、ストリームを使用しません。私はtoArrayがあなたの質問されたすべてのドキュメントをメモリに読み込んで、一度にそれらを返すと思う。私はカーソルストリームを介して発見されるとすぐに最初のドキュメントを返すことができるようにしたい。 –

関連する問題