【问题标题】:Haskell Mongodb insert records from fileHaskell Mongodb 从文件中插入记录
【发布时间】:2017-03-09 08:47:46
【问题描述】:

我尝试编写一个程序来读取文件并将信息存储在 mongoldb 集合中。该程序基于 mongodb 驱动程序的示例程序。 对于测试,我在 testdaten 中定义了一些常量,程序使用这些数据。当我尝试插入文件数据时,出现类型错误:

insertMany "daten" getWetterDaten 无法匹配预期类型 [Document] 与实际类型IO [[Data.Bson.Field]] 在insertMany的第二个参数中,即getWetterDaten 在 do 块的结构中:insertMany "daten" getWetterDaten

我知道问题在于 testdaten 有 Type testDaten :: [[Data.Bson.Field]] 和getWetterDaten 有Type 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]

【问题讨论】:

  • 第二个错误很简单 - 将Field 添加到您的导入列表中。第一个不是一个完整的错误(除此之外:ghc 给出了非常大的错误,但如果你真的阅读了整个内容,它们会非常精确和信息丰富)所以实际上不可能知道它来自哪里,但我猜你想要lift getWetterDaten &gt;&gt;= insertMany "daten" 之类的东西。当然,每次执行insert 时都会读取文件,这可能不是您想要的。
  • 谢谢,我尝试了 liftM getWetterDaten >>= insertMany "daten3" 但出现错误:无法匹配预期类型 'Control.Monad.Trans.Reader.ReaderT Database.MongoDB.Query.MongoContext IO [Document]' 实际类型为 'm0 a10 -> m0 r0' 可能原因:'liftM' 应用于太少的参数 在 '(>>=)' 的第一个参数中,即 'liftM getWetterDaten

标签: mongodb haskell


【解决方案1】:

我找到了一个解决方案,可以将数据作为参数传递给 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]

【讨论】:

    猜你喜欢
    • 2016-08-11
    • 2016-04-04
    • 2011-07-05
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2020-08-10
    • 1970-01-01
    相关资源
    最近更新 更多