@@ -1,5 +1,5 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE RecordWildCards #-}
1+{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards #-}
33
44-------------------------------------------------------------------------------
55-- |
@@ -36,6 +36,7 @@ module Database.Bloodhound.Client
3636 , searchAll
3737 , searchByIndex
3838 , searchByType
39+ , scanSearch
3940 , refreshIndex
4041 , mkSearch
4142 , mkAggregateSearch
@@ -482,6 +483,40 @@ searchByType (IndexName indexName)
482483 (MappingName mappingName) = bindM2 dispatchSearch url . return
483484 where url = joinPath [indexName, mappingName, "_search"]
484485
486+scanSearch' :: MonadBH m => Search -> m (Maybe ScrollId)
487+scanSearch' search = do
488+ let url = joinPath ["_search"]
489+ search' = search { searchType = SearchTypeScan }
490+ resp' <- bindM2 dispatchSearch url (return search')
491+ let msr = decode' $ responseBody resp' :: Maybe (SearchResult ())
492+ msid = maybe Nothing scrollId msr
493+ return msid
494+
495+scroll' :: (FromJSON a, MonadBH m) => Maybe ScrollId -> m ([Hit a], Maybe ScrollId)
496+scroll' Nothing = return ([], Nothing)
497+scroll' (Just sid) = do
498+ url <- joinPath ["_search/scroll?scroll=1m"]
499+ resp' <- post url (Just . L.fromStrict $ T.encodeUtf8 sid)
500+ let msr = decode' $ responseBody resp' :: FromJSON a => Maybe (SearchResult a)
501+ resp = case msr of
502+ Just sr -> (hits $ searchHits sr, scrollId sr)
503+ _ -> ([], Nothing)
504+ return resp
505+
506+simpleAccumilator :: (FromJSON a, MonadBH m) => [Hit a] -> ([Hit a], Maybe ScrollId) -> m ([Hit a], Maybe ScrollId)
507+simpleAccumilator oldHits (newHits, Nothing) = return (oldHits ++ newHits, Nothing)
508+simpleAccumilator oldHits ([], _) = return (oldHits, Nothing)
509+simpleAccumilator oldHits (newHits, msid) = do
510+ (newHits', msid') <- scroll' msid
511+ simpleAccumilator (oldHits ++ newHits) (newHits', msid')
512+
513+scanSearch :: (FromJSON a, MonadBH m) => Search -> m [Hit a]
514+scanSearch search = do
515+ msid <- scanSearch' search
516+ (hits, msid') <- scroll' msid
517+ (totalHits, _) <- simpleAccumilator [] (hits, msid')
518+ return totalHits
519+
485520-- | 'mkSearch' is a helper function for defaulting additional fields of a 'Search'
486521-- to Nothing in case you only care about your 'Query' and 'Filter'. Use record update
487522-- syntax if you want to add things like aggregations or highlights while still using