5

मैं node.js. में एक फ़ाइल (300,000 लाइनें) पढ़ रहा हूँ मैं उन्हें स्टोर करने के लिए 5,000 लाइनों के बैचों में अन्य एप्लिकेशन (लोचदार खोज) में लाइन भेजना चाहता हूं। इसलिए जब भी मैं 5,000 लाइनों को पढ़ना समाप्त करता हूं, तो मैं उन्हें एडीआई के माध्यम से उन्हें स्टोर करने के लिए एलआईसी के माध्यम से थोक में भेजना चाहता हूं और फिर बाकी फाइल को पढ़ना जारी रखता हूं और हर 5,000 लाइन को थोक में भेजता हूं।गैर-अवरुद्ध व्यवहार में नहीं, नोड.जेएस या जावास्क्रिप्ट के साथ फ़ाइल की रेखाओं को कैसे पढ़ा जाए?

मैं इस कार्य के लिए जावा (या ऐसे सी, सी ++, अजगर, आदि के रूप में किसी अन्य अवरुद्ध भाषा) का उपयोग करना चाहते हैं, तो मैं कुछ इस तरह करेंगे:

int countLines = 0; 
String bulkString = ""; 
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("filePath.txt"))); 
while ((currentLine = br.readLine()) != null) { 
    countLines++; 
    bulkString += currentLine; 
    if(countLines >= 5000){ 
      //send bulkString to Elasticsearch via APIs 
      countLines = 0; 
      bulkString = ""; 
    } 
} 

अगर मैं चाहता हूँ Node.js साथ एक ही बात करते हैं, मुझे क्या करना होगा:

var countLines = 0; 
var bulkString = ""; 
var instream = fs.createReadStream('filePath.txt'); 
var rl = readline.createInterface(instream, outstream); 
rl.on('line', function(line) { 
    if(countLines >= 5000){ 
      //send bulkString to via APIs 
      client.bulk({ 
      index: 'indexName', 
      type: 'type', 
      body: [bulkString] 
      }, function (error, response) { 
      //task is done 
      }); 
      countLines = 0; 
      bulkString = ""; 
    } 
} 

समस्या Node.js साथ यह इतना गैर अवरुद्ध यह अगले भेजने से पहले पहले एपीआई प्रतिक्रिया के लिए प्रतीक्षा नहीं करता है लाइनों का बैच। मुझे पता है कि यह done.js के लिए लाभ के रूप में गिना जा सकता है क्योंकि यह I/O की प्रतीक्षा नहीं करता है, लेकिन समस्या यह है कि यह Elasticsearch को बहुत अधिक डेटा भेजता है। इसके लिए लोचदार खोज की कतार पूरी हो जाएगी और यह अपवाद फेंक देगा।

मेरा प्रश्न से पहले ही अगली पंक्तियों को पढ़ने के लिए जारी है या यह Elasticsearch को लाइनों के अगले बैच भेजता पहले कि मैं कैसे कर सकते हैं एपीआई से प्रतिक्रिया के लिए प्रतीक्षा करने Node.js है।

मुझे पता है कि मैं कतार आकार बढ़ाने के लिए Elasticsearch में कुछ पैरामीटर सेट कर सकता हूं, लेकिन मुझे इस मुद्दे के लिए node.js के व्यवहार को अवरुद्ध करने में रूचि है। मैं कॉलबैक की अवधारणा से परिचित हूं, लेकिन मैं इस परिदृश्य में कॉलबैक का उपयोग करने के तरीके के बारे में नहीं सोच सकता, ताकि नोड-डीजे को गैर-अवरुद्ध मोड में Elasticsearch API को कॉल करने से रोका जा सके।

उत्तर

4

पियरे का जवाब सही है। मैं सिर्फ एक कोड सबमिट करना चाहता हूं जो दिखाता है कि हम नोड.जेएस की गैर-अवरोधक अवधारणा से कैसे लाभ उठा सकते हैं, लेकिन साथ ही, एक समय में बहुत से अनुरोधों के साथ Elasticsearch को जबरदस्त न करें।

यहाँ है कि आप कतार आकार सीमा निर्धारित करके कोड एक लचीलापन देने के लिए उपयोग कर सकते हैं एक छद्म कोड है:

var countLines = 0; 
var bulkString = ""; 
var queueSize = 3;//maximum of 3 requests will be sent to the Elasticsearch server 
var batchesAlreadyInQueue = 0; 
var instream = fs.createReadStream('filePath.txt'); 
var rl = readline.createInterface(instream, outstream); 
rl.on('line', function(line) { 
    if(countLines >= 5000){ 
      //send bulkString to via APIs 
      client.bulk({ 
      index: 'indexName', 
      type: 'type', 
      body: [bulkString] 
      }, function (error, response) { 
       //task is done 
       batchesAlreadyInQueue--;//we will decrease a number of requests that are already sent to the Elasticsearch when we hear back from one of the requests 
       rl.resume(); 
      }); 
      if(batchesAlreadyInQueue >= queueSize){ 
       rl.pause(); 
      } 
      countLines = 0; 
      bulkString = ""; 
    } 
} 
2

अपने //task is done के बाद rl.resume() के ठीक बाद rl.pause() का उपयोग करें।

ध्यान दें कि आपके पास विराम को कॉल करने के बाद कुछ और पंक्ति घटना हो सकती है।

+0

धन्यवाद, मेरे लिए काम किया। – Soheil

संबंधित मुद्दे