我写了以下程序:
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
import Control.Exception (bracket)
import Control.Monad (forM)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Data.List.Split (chunksOf)
import qualified Database.MongoDB as M
import qualified Data.Text as T
db :: M.Action IO a -> IO a
db action = do
pipe <- M.connect (M.host "127.0.0.1")
res <- M.access pipe M.master "haskell" action
M.close pipe
return res
main = do
let docs = (flip map) [0..199999] $ \i ->
["name" M.=: (T.pack $ "name " ++ (show i))]
ids <- forM (chunksOf 50000 docs) $ \chunk ->
db $ M.insertAll "bigCollection" chunk
cur <- db $ M.find $ (M.select [] "bigCollection") {M.limit = 100000, M.batchSize = 100000}
returnedDocs <- db $ drainCursor cur
putStrLn $ show $ length returnedDocs
drainCursor :: M.Cursor -> M.Action IO [M.Document]
drainCursor !cur = drainCursor' cur []
where
drainCursor' cur res = do
batch <- M.nextBatch cur
if null batch
then return res
else drainCursor' cur (res ++ batch)
在插入所有数据后,它会停留在等待来自服务器的数据上。我认为这是因为它在读取数据之前关闭了连接。我试过BangPatterns和seq函数,括号函数,但没有成功。只有当我保持连接打开时(通过注释掉M.close)它才有效。有人可以推荐我如何规避这种情况吗?
提前致谢。
答案 0 :(得分:2)
要扩展@ chi的评论,您可能想要替换
cur <- db $ M.find $ (M.select [] "bigCollection")
{M.limit = 100000, M.batchSize = 100000}
returnedDocs <- db $ drainCursor cur
通过
returnedDocs <- db $ do
cur <- M.find $ (M.select [] "bigCollection")
{M.limit = 100000, M.batchSize = 100000}
drainCursor cur
我从未使用过mongoDB,但我确信数据库游标只能在创建它的连接中使用。