A boilerplate snaplet to conveniently allow bloodhound ElasticSearch functions to be lifted into snap web handlers.
- Add the
BloodhoundEnv
to your apps core state:
import Snap.Snaplet.Bloodhound
data App = App
{...
,_bloodhoundEnv :: Snaplet BloodhoundEnv
,...
}
- Derive (or manually create) lenses:
makeLenses ''App
- Implement a
HasBHEnv
instance:
instance HasBHEnv App where
bhEnv = bloodhoundEnv . bhEnv
- In your initialisation function, initialise like so, providing a value for
server
in thedevel.cfg
file found under the corresponding snaplet directorysnaplets/bloodhound/devel.cfg
.
app :: SnapletInit App App
app = makeSnaplet "app" "Your application" Nothing $ do
...
bloodhoundSnaplet <- nestSnaplet "bloodhound" bloodhoundEnv bloodhoundEnvInit
...
return $ App ... bloodhoundSnaplet ...
- You should find
Handler b App
now has aMonadBH
instance, and so bloodhound functions that require one can be called in your handler. E.G:
-- Some bloodhound search function
searchYourDocuments :: MonadBH m => Search -> m Reply
searchYourDocuments = searchByType yourIndexName yourMappingName
-- Can now be used inside your handlers.
doSomethingWithYourDocs :: Handler App App ()
doSomethingWithYourDocs = do
eDoc :: Either EsError (SearchResult YourDocument) <- parseEsResponse =<< searchYourDocuments
case eDoc of
Left err
-> fail . show $ err
Right (SearchResult _took _timedout _shards (SearchHits _hTotal _hMaxScore hits) _hAggs _hmScrollId)
-> map (\(Hit _hIndex _hType _hDocId _hScore hSource _hHighlight) -> case hSource of
Nothing -> ...
Just (YourDocument ...) -> ...
)
hits