2017-03-09 137 views
0

我嘗試編寫一個讀取文件並將信息存儲在mongoldb集合中的程序。該程序基於mongodb驅動程序的示例程序。 爲了測試,我在testdaten中定義了一些常量,並且程序使用這些數據。當我嘗試插入的文件數據,我得到一個錯誤類型:Haskell Mongodb從文件中插入記錄

insertMany「回到名單Daten」 getWetterDaten 無法匹配,期望型[Document] 與實際類型IO [[Data.Bson.Field]]insertMany第二個參數,即getWetterDaten 在語句一個do塊:insertMany "daten" getWetterDaten

我知道,問題是,testdaten有Type testDaten :: [[Data.Bson.Field]]getWetterDatenType getWetterDaten :: IO [[Data.Bson.Field]], 但我怎麼能解決這個問題?

當我嘗試作爲參數傳遞的數據insertData2我得到的消息:

Couldn't match type ‘Control.Monad.Trans.Reader.ReaderT 
        Database.MongoDB.Query.MongoContext m1 [Value]’ 

這絕對是遠遠超出了我的Haskell的理解。

另一種看法是,如果我嘗試包括類型聲明 我得到一個錯誤信息:

Not in scope: type constructor or class `Data.Bson.Field` 

什麼是文件數據插入到MongoDB的正確方法是什麼?

{-# LANGUAGE OverloadedStrings #-} 
    {-# LANGUAGE ExtendedDefaultRules #-} 
    module TestModule where 

    import Database.MongoDB (Action, Document, Document, Value, access, 
           close, connect, delete, exclude, find, 
           host, insertMany, master, project, rest, 
           select, sort, (=:)) 

    main :: IO() 
    main = do 
     wetterDaten <- getWetterDaten 
     pipe  <- connect (host "127.0.0.1") 
     e   <- access pipe master "wetter2017" run 
     close pipe 
     print e 

    --run :: Action IO() 
    run = do 
     clearData 
     insertData 
     return() 

    clearData :: Action IO() 
    clearData = delete (select [] "daten") 

    --insertData :: Action IO [Value] 
    insertData = do 
    **insertMany "daten" testDaten** 

    insertData2 :: Action IO [Value] 
    insertData2 = do 
    **insertMany "daten" getWetterDaten** 

    testDaten = [["data" =: "Zeile0"],["data" =: "Zeile1"], 
       ["data" =: "Zeile2"],["data" =: "Zeile3"]] 

    getWetterDaten = do 
    fileContents <- fmap lines $ readFile "data.txt" 
    let wetterDaten = map makeMongo fileContents 
    return wetterDaten 

    makeMongo x = [ "data"  =: x] 
+0

第二個錯誤是簡單 - 加上'Field'到你的導入列表。首先不是一個完整的錯誤(撇開:ghc給出了很大的錯誤,但如果你真的閱讀完整的東西,它們是非常精確的和信息量豐富的),所以不可能告訴它來自哪裏,但我猜你想要的東西像'lift getWetterDaten >> = insertMany「daten」'。當然,每次執行'insert'時都會讀取文件,這可能不是您想要的。 – user2407038

+0

謝謝,我試過liftM getWetterDaten >> = insertMany「daten3」但有錯誤:無法匹配預期的類型'Control.Monad.Trans.Reader.ReaderT Database.MongoDB.Query.MongoContext IO [Document]' with實際類型'm0 a10 - > m0 r0' 可能的原因:'liftM'應用於太少的參數 在'(>> =)'的第一個參數中,即'liftM getWetterDaten – Ralli

回答

0

我發現,通過將數據作爲參數傳遞給insertData2有效的解決方案:

{-# LANGUAGE OverloadedStrings #-} 
    {-# LANGUAGE ExtendedDefaultRules #-} 
    module TestModule2 where 

    import Database.MongoDB (Action, Document, Document, Value, access, 
           close, connect, delete, exclude, find, 
           host, insertMany, master, project, rest, 
           select, sort, (=:)) 

    main :: IO() 
    main = do 
     wetterDaten <- getWetterDaten 
     processMongo wetterDaten 
     return() 

    processMongo :: [Document] -> IO()  
    processMongo wetterDaten = do 
     pipe  <- connect (host "127.0.0.1") 
     e   <- access pipe master "wetter2017" (run wetterDaten) 
     close pipe 
     print e 

    run :: [Document] -> Action IO() 
    run wetterDaten = do 
     clearData 
     insertData 
     clearData2 
     insertData2 wetterDaten 
     return() 

    clearData :: Action IO() 
    clearData = delete (select [] "daten") 

    clearData2 :: Action IO() 
    clearData2 = delete (select [] "daten2") 

    insertData :: Action IO [Value] 
    insertData = do 
    insertMany "daten" testDaten 

    insertData2 :: [Document] -> Action IO [Value] 
    insertData2 wetterDaten = do 
    insertMany "daten2" wetterDaten 

    testDaten :: [Document] 
    testDaten = [["data" =: "Zeile0"],["data" =: "Zeile1"], 
       ["data" =: "Zeile2"],["data" =: "Zeile3"]] 

    getWetterDaten :: IO [Document] 
    getWetterDaten = do 
    fileContents <- fmap lines $ readFile "data.txt" 
    let wetterDaten = map makeMongo fileContents 
    return wetterDaten 

    makeMongo :: String -> Document 
    makeMongo x = [ "data"  =: x]