2015-04-22 7 views
5

मुझे बड़ी फ़ाइल (~ 1 जीबी) पढ़ने की जरूरत है, इसे संसाधित करें और डीबी में सहेजें। मेरे समाधान है कि तरह लग रहा है:क्लोजर - बड़ी फ़ाइल प्रसंस्करण को गति दें

data.txt

प्रारूप: [id],[title]\n

1,Foo 
2,Bar 
... 

कोड

(ns test.core 
    (:require [clojure.java.io :as io] 
      [clojure.string :refer [split]])) 

(defn parse-line 
    [line] 
    (let [values (split line #",")] 
    (zipmap [:id :title] values))) 

(defn run 
    [] 
    (with-open [reader (io/reader "~/data.txt")] 
    (insert-batch (map parse-line (line-seq reader))))) 

; insert-batch just save vector of records into database 

लेकिन इस कोड में अच्छी तरह से है क्योंकि यह पहले से काम नहीं करता, सभी लाइनों को पार्स करें और फिर उन्हें डेटाबेस में भेजें।

मुझे लगता है कि आदर्श समाधान read line -> parse line -> collect 1000 parsed lines -> batch insert them into database -> repeat until there is no lines होगा। दुर्भाग्यवश, मुझे नहीं पता कि इसे कैसे कार्यान्वित किया जाए।

उत्तर

11

सुझाव एक:

  • उपयोग line-seq लाइनों की एक आलसी अनुक्रम प्राप्त करने के लिए,

  • उपयोग मानचित्र प्रत्येक पंक्ति विभाजित करने,

(अब तक इस से मेल खाता है क्या आप कर रहे हैं)

  • उपयोग partition-all बैच में पार्स लाइनों के अपने आलसी अनुक्रम विभाजन, और फिर

    doseq साथ
  • उपयोग डालने बैच डेटाबेस के लिए प्रत्येक बैच लिखने के लिए।

और एक उदाहरण:

(->> (line-seq reader) 
    (map parse-line) 
    (partition-all 1000) 
    (#(doseq [batch %] 
     (insert-batch batch)))) 
+0

बढ़िया काम करता है! आपका बहुत बहुत धन्यवाद। मुझे लगता है कि मुझे आलसी अनुक्रमों को समझने में समस्या है। क्या आप किसी भी अच्छे स्रोत के बारे में जानते हैं जो मुझे बेहतर समझने में मदद कर सकता है? – user1518183

+2

[क्लोजर का जॉय] (http://www.manning.com/fogus2/) बहुत अच्छा है। – bsvingen

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