我对Haskell相当新鲜;我已经阅读了无数的教程和其他资源,但每当我决定尝试编写远程有用的程序时,我通常都不知道从哪里开始。我最近在播放一个播客,其中Gabriel Gonzalez谈到了保持激励的最佳方式是如何将它用于项目并且只是写作,所以我真的想用它来完成我手边的任务。
所以,我有一个Mongo数据库,它不断更新定期抓取的项目和Elasticsearch数据库。前者经常会更新我之前已经删除的项目,而后者则填充了独特的项目。为了达到这个目的,我有一个脚本(1000行Node.js),它一直在运行并逐一消耗Mongo数据库中的项目,进行一些检查以查看它是否已经存在于Elasticsearch数据库中,如果不是,则添加它;之后,它从Mongo中删除了。然而,这个剧本完全混乱。
我一直想在Haskell中做这件事,因为Haskell非常适合以我自己读过和听过的方式来控制IO,因为我喜欢保持纯函数来转换数据和程序的一部分实际执行IO分离。我还假设一个有效的Haskell解决方案会更简洁,并且在以后更改内容时更容易推理。
到目前为止,我已经设法使用mongoDB包来按照教程在Mongo中进行CRUD操作,但是仍然有很多我不了解它的工作方式。我发现使用Bloodhound包更难以在Elasticsearch中做同样的事情,我完全不知道如何将事情拼凑在一起,特别是在确保相关项目仅在成功添加后从Mongo中删除时到Elasticsearch。
我知道这是一个非常广泛的问题,但如果有人对此有所了解,或者只是能给我一些方向,我将不胜感激。事实上,非常感谢所有的帮助。
答案 0 :(得分:5)
我喜欢保留用于转换数据的纯函数的想法 并且程序的各个部分实际上将IO分开。
如果你是从Haskell开始的话,我建议你把它留在后面,只需构建一个即使它到处都有IO
的解决方案。当您获得信心时,您将学习如何重新构建代码。
我完全不知道如何将事情拼凑在一起, 特别是在确保仅删除相关项目的同时 成功添加到Elasticsearch后,来自Mongo。
除非我错过了某些内容,否则这似乎是非常简单的程序逻辑!
如果您拥有以下(完全发明的,非常简化的)功能
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)
当然,还有更多事情需要考虑。插入弹性搜索时如果抛出exception该怎么办?您可能需要使用来自bracket
的try
,finally
,onException
和Control.Exception
等功能。