2015-04-22 32 views
5

我需要讀大文件(〜1GB),處理它並保存到數據庫。我的解決方案看起來像這樣:Clojure - 加速大文件處理

的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

[Clojure的歡樂](http://www.manning.com/fogus2/)很棒。 – bsvingen