johnny-john
johnny-john

Reputation: 854

Haskell mongoDB driver (1.3.1) cursor iteration example

I am a beginner in Haskell and I tend to learn by doing.

Could someone provide me an example of how to use the cursor with nextBatch or nextN? http://hackage.haskell.org/packages/archive/mongoDB/1.3.1/doc/html/Database-MongoDB-Query.html#g:12

Tried something like this (I tried to write a custom iteration function, where f is a function which I want to map over all documents)

let cursor = Mdb.find (Mdb.select selector collection)
       -- consume :: IO ()
       consume = do
                r <- runAction db $ Mdb.nextBatch =<< cursor
                if length (fromRight r) == 0
                    then return ()
                    else do
                        mapM_ f (fromRight r)
                        consume
   consume

Now this runs in an infinite loop, always returning the same set of documents. I guess the cursor is never being modified? The cursor type itself has an MVar as one of it's elements, first I thought that would be updated when I do a nextBatch, but that never happens.

Maybe I should rewrite the recursion the way it stays in the Action monad (see mongo driver), rather than IO? I am stuck.

Upvotes: 2

Views: 262

Answers (1)

Fedor Gogolev
Fedor Gogolev

Reputation: 10551

When you write let cursor = Mdb.find (Mdb.select selector collection) it creates Action m Cursor that will be executed only in Action m context, so actually you created new cursor each =<< cursor time.

Yes, i think that you should rewrite you function in mostly Action m context. For example:

consume :: IO ()
consume = void $ runAction db $ do
    cursor <- Mdb.find $ Mdb.select selector collection
    go cursor
  where
    go cursor = Mdb.nextBatch cursor >>= \result -> case result of
        [] -> return ()
        xs -> mapM_ f xs >> go cursor

Upvotes: 2

Related Questions