| CARVIEW |
bloodhound: Elasticsearch client library for Haskell
Modules
[Index] [Quick Jump]
- Database
- Database.Bloodhound
- Database.Bloodhound.Client
- Common
- Dynamic
- ElasticSearch7
- OpenSearch1
- OpenSearch2
- Database.Bloodhound.Requests
- Database.Bloodhound.Types
- Database.Bloodhound
Downloads
- bloodhound-0.26.0.0.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
| Versions [RSS] | 0.1.0.0, 0.1.0.1, 0.1.0.2, 0.2.0.0, 0.3.0.0, 0.4.0.0, 0.4.0.1, 0.4.0.2, 0.5.0.0, 0.5.0.1, 0.6.0.0, 0.6.0.1, 0.7.0.0, 0.7.0.1, 0.8.0.0, 0.9.0.0, 0.10.0.0, 0.11.0.0, 0.11.1.0, 0.12.0.0, 0.12.1.0, 0.13.0.0, 0.14.0.0, 0.15.0.0, 0.15.0.1, 0.15.0.2, 0.16.0.0, 0.18.0.0, 0.19.0.0, 0.19.1.0, 0.20.0.0, 0.20.0.1, 0.20.0.2, 0.21.0.0, 0.22.0.0, 0.23.0.0, 0.23.0.1, 0.24.0.0, 0.25.0.0, 0.26.0.0 (info) |
|---|---|
| Change log | changelog.md |
| Dependencies | aeson (>=2.0 && <3), base (>=4.14 && <5), blaze-builder (>=0.1 && <1), bytestring (>=0.10.0 && <1), containers (>=0.5.0.0 && <1), exceptions (>=0.1 && <1), hashable (>=1 && <2), http-client (>=0.4.30 && <1), http-types (>=0.8 && <1), microlens (>=0.4 && <1), mtl (>=1.0 && <3), network-uri (>=2.6 && <3), optics-core (>=0.4 && <0.5), scientific (>=0.3.0.0 && <1), template-haskell (>=2.10 && <3), text (>=0.11 && <3), time (>=1.4 && <2), unordered-containers (>=0.1 && <1), vector (>=0.10.9 && <1), versions (>=5.0.2 && <7) [details] |
| Tested with | ghc ==8.10.7, ghc ==9.0.2, ghc ==9.2.8, ghc ==9.4.8, ghc ==9.6.6, ghc ==9.8.4, ghc ==9.10.1, ghc ==9.12.1 |
| License | BSD-3-Clause |
| Copyright | 2018 Chris Allen |
| Author | Chris Allen |
| Maintainer | foss@difolco.dev |
| Uploaded | by gdifolco at 2025-10-19T11:16:57Z |
| Category | Database, Search |
| Home page | https://github.com/bitemyapp/bloodhound.git#readme |
| Bug tracker | https://github.com/bitemyapp/bloodhound.git/issues |
| Source repo | head: git clone https://github.com/bitemyapp/bloodhound.git |
| Distributions | LTSHaskell:0.23.0.1, NixOS:0.23.0.1, Stackage:0.26.0.0 |
| Reverse Dependencies | 5 direct, 3 indirect [details] |
| Downloads | 27124 total (124 in the last 30 days) |
| Rating | 2.0 (votes: 2) [estimated by Bayesian average] |
| Your Rating |
|
| Status | Docs available [build log] Last success reported on 2025-10-19 [all 1 reports] |
Readme for bloodhound-0.26.0.0
[back to package description]Bloodhound


Elasticsearch client and query DSL for Haskell
Why?
Search doesn't have to be hard. Let the dog do it.
Endorsements
"Bloodhound makes Elasticsearch almost tolerable!" - Almost-gruntled user
"ES is a nightmare but Bloodhound at least makes it tolerable." - Same user, later opinion.
Version compatibility
See the Github compatibility workflow for a listing of Elasticsearch and OpenSearch versions we test against.
The workflow executions can be seen in the Github actions view.
Stability
Bloodhound is stable for production use. I will strive to avoid breaking API compatibility from here on forward, but dramatic features like a type-safe, fully integrated mapping API may require breaking things in the future.
Testing
The Bloodhound project uses Github workflows using Cabal to test for regressions and compatibility. A convenient development environment is provided by Nix and a Makefile, though the project can be built with only Cabal.
To run the tests:
- Get into the Nix environment by running
nix develop(ornix-shellfor a non-flake setup) - Start Elasticsearch defined by
docker-compose.yml:make compose - Run the tests with Cabal:
cabal test
The second step can be left out if ElasticSearch (or OpenSearch) is started manually.
Contributions
Any contribution is welcomed, for consistency reason ormolu is used.
Hackage page and Haddock documentation
https://hackage.haskell.org/package/bloodhound
Elasticsearch Tutorial
It's not using Bloodhound, but if you need an introduction to or overview of Elasticsearch and how to use it, you can use this screencast.
Examples
See the examples directory for example code.
Index a document
indexDocument testIndex defaultIndexDocumentSettings exampleTweet (DocId "1")
{-
IndexedDocument
{ idxDocIndex = "twitter"
, idxDocType = "_doc"
, idxDocId = "1"
, idxDocVersion = 3
, idxDocResult = "updated"
, idxDocShards =
ShardResult
{ shardTotal = 1
, shardsSuccessful = 1
, shardsSkipped = 0
, shardsFailed = 0
}
, idxDocSeqNo = 2
, idxDocPrimaryTerm = 1
}
-}
Fetch documents
let query = TermQuery (Term "user" "bitemyapp") boost
let search = mkSearch (Just query) boost
searchByIndex @_ @Tweet testIndex search
{-
SearchResult
{ took = 1
, timedOut = False
, shards =
ShardResult
{ shardTotal = 1
, shardsSuccessful = 1
, shardsSkipped = 0
, shardsFailed = 0
}
, searchHits =
SearchHits
{ hitsTotal = HitsTotal { value = 2 , relation = HTR_EQ }
, maxScore = Just 0.18232156
, hits =
[ Hit
{ hitIndex = IndexName "twitter"
, hitDocId = DocId "1"
, hitScore = Just 0.18232156
, hitSource =
Just
Tweet
{ user = "bitemyapp"
, postDate = 2009-06-18 00:00:10 UTC
, message = "Use haskell!"
, age = 10000
, location = LatLon { lat = 40.12 , lon = -71.3 }
}
, hitSort = Nothing
, hitFields = Nothing
, hitHighlight = Nothing
, hitInnerHits = Nothing
}
, Hit
{ hitIndex = IndexName "twitter"
, hitDocId = DocId "2"
, hitScore = Just 0.18232156
, hitSource =
Just
Tweet
{ user = "bitemyapp"
, postDate = 2009-06-18 00:00:10 UTC
, message = "Use haskell!"
, age = 10000
, location = LatLon { lat = 40.12 , lon = -71.3 }
}
, hitSort = Nothing
, hitFields = Nothing
, hitHighlight = Nothing
, hitInnerHits = Nothing
}
]
}
, aggregations = Nothing
, scrollId = Nothing
, suggest = Nothing
, pitId = Nothing
}
-}
Contributors
- Chris Allen
- Liam Atkinson
- Christopher Guiney
- Curtis Carter
- Michael Xavier
- Bob Long
- Maximilian Tagher
- Anna Kopp
- Matvey B. Aksenov
- Jan-Philip Loos
- Gautier DI FOLCO
Possible future functionality
Span Queries
Beginning here: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html
Function Score Query
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
Node discovery and failover
Might require TCP support.
Support for TCP access to Elasticsearch
Pretend to be a transport client?
Bulk cluster-join merge
Might require making a lucene index on disk with the appropriate format.
GeoShapeQuery
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html
GeoShapeFilter
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html
Geohash cell filter
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geohash-cell-filter.html
HasChild Filter
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html
HasParent Filter
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html
Indices Filter
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-indices-filter.html
Query Filter
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html
Script based sorting
Collapsing redundantly nested and/or structures
The Seminearring instance, if deeply nested can possibly produce nested structure that is redundant. Depending on how this affects ES performance, reducing this structure might be valuable.
Runtime checking for cycles in data structures
check for n > 1 occurrences in DFS:
https://hackage.haskell.org/package/stable-maps-0.0.5/docs/System-Mem-StableName-Dynamic.html
https://hackage.haskell.org/package/stable-maps-0.0.5/docs/System-Mem-StableName-Dynamic-Map.html
Photo Origin
Photo from HA! Designs: https://www.flickr.com/photos/hadesigns/