2016-11-06 73 views
2

我是Haskell的新手,我已經閱讀了無數的教程和其他資源,但每當我決定嘗試編寫任何遠程有用的程序時,我通常甚至不知道從哪裏開始。我最近在聽一個播客,Gabriel Gonzalez在談論如何保持動力的最佳方式是實際將它用於項目並寫作,所以我真的想用它來完成我手頭的任務。如何使用Haskell將某些數據從一個數據庫移動到另一個數據庫?

因此,我有一個Mongo數據庫,它不斷更新正在被定期抓取的項目和一個Elasticsearch數據庫。前者會經常更新我之前已經刮過的物品,而後者則填充了獨特的物品。爲了達到這個目的,我有一個腳本(1000行Node.js),它不斷地運行並逐個使用Mongo數據庫中的項目,做一些檢查以確定它是否已經存在於Elasticsearch數據庫中,如果沒有,就添加它;之後,它從Mongo中刪除。然而這個腳本是一團糟。

我一直想在Haskell中做到這一點,因爲Haskell非常適合從我讀過和聽過的受控方式管理IO,並且因爲我喜歡保持純函數來轉換數據和程序中實際執行IO的部分是分開的。我還假設Haskell解決方案將更加簡潔,並且在稍後進行更改時更容易推理。

到目前爲止,我已經設法使用mongoDB包在Mongo中執行CRUD操作,但仍然有很多事情我不明白它的工作原理。我發現使用Bloodhound包在Elasticsearch中做同樣的事情很困難,而且我完全不知道如何將事情組合在一起,特別是在確保相關項目在成功添加後才從Mongo中刪除到Elasticsearch。

我知道這是一個非常廣泛的問題,但如果有人對此有所瞭解,或者只是能夠給我一些指導,我將不勝感激。事實上,所有的幫助將非常感激。

+0

這個問題太寬泛,無法通過堆棧溢出格式以有用的方式回答。你可能會在這裏得到更好的結果,將目前有困難的東西提煉成一小段自包含的代碼,然後問一個關於它的問題。 – duplode

回答

5

我喜歡保留用於轉換數據的純函數 和實際執行IO的程序部分分離的想法。

如果你開始哈斯克爾我勸你離開這個在腦後,只是建立,如果有IO無處不在的作品,甚至一個解決方案。隨着您獲得信心,您將學習如何重構代碼。

我完全難倒,我怎麼會拼湊的東西放在一起, 尤其是同時確保相關項目只能從蒙戈已經成功添加到Elasticsearch之後被刪除 。

除非我錯過了一些事情,那看起來很簡單的程序邏輯!

如果您有以下(完全發明,非常簡化的)函數

getDocumentFromMongo :: MongoGonnection -> IO Document 

deleteFromMongo :: MongoConnection -> Document -> IO() 

isPresentInElastic :: ElasticConnection -> Document -> IO Bool 

insertInElastic :: ElasticConnection -> Document -> IO() 

你可以寫這樣一個無限循環:

loader :: MongoConnection -> ElasticConnection -> IO r -- runs forever 
loader mongoConn elasticConn = forever (do 
    document <- getDocumentFromMongo mongoConn 
    existsInElastic <- isPresentInElastic elasticConn document 
    if existsInElastic 
     then return() 
     else insertInElastic elasticConn document 
    deleteFromMongo mongoConn document) 

當然,還有更多的事情要考慮。插入Elastic Search時引發exception怎麼辦?您大概需要使用try,bracket,finallyonException之類的函數,從Control.Exception

此外,也許需要某種程度的併發性。這也有manygoodlibraries

+0

謝謝,這是一個很好的答案。正如你最後指出的那樣,更新Elasticsearch更新失敗時要做的事情是我需要弄清楚的事情之一。我來自Python,並且您描述異常處理的方式聽起來與Python中的處理方式類似,我認爲這不是Haskell中的情況。 此外,當它按照您描述的方式永久運行時,它如何處理等待Mongo數據庫爲空並且沒有消耗任何東西的情況? –

+0

@Nicholas Tidemann Haskell對信號錯誤有兩種風味:異常和和類型,比如'Either'或'Maybe'。 http://book.realworldhaskell.org/read/error-handling.html至於等待,你可以使用'Control.Concurrent'中的'threadDelay :: Int - > IO()'來實現一個簡單的輪詢機制。 http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Concurrent.html#v:threadDelay – danidiaz

+0

對,我至少熟悉'Either'和'Maybe',通過閱讀關於他們很多,我會看看我能否解決。至於等待,我也到達'threadDelay'是首選的方式,與Python中的'time.sleep'類似,但由於它是併發的,我猜它的工作原理有點不同。我會看看我能不能取得進展,謝謝你的幫助。 –

相關問題