git.iko.soy/typeable/bloodhound
on master help sign in
fine
5ccffd3Chris Allen
README.org → README.mdrenamed+240−218
@@ -1,47 +1,53 @@
1−* Bloodhound
1+Bloodhound
2+==========
2
3
3−#+CAPTION: Bloodhound (dog)
4−[[./bloodhound.jpg]]
4+![Bloodhound (dog)](./bloodhound.jpg)
5
5
6+[<https://travis-ci.org/bitemyapp/bloodhound.svg>](https://travis-ci.org/bitemyapp/bloodhound)
6
7
7−#+CAPTION: Build Status
8+[<https://img.shields.io/hackage/v/bloodhound.svg?style=flat>](https://hackage.haskell.org/package/bloodhound/)
8−[[https://travis-ci.org/bitemyapp/bloodhound][https://travis-ci.org/bitemyapp/bloodhound.svg]]
9
9
10−[[https://img.shields.io/hackage/v/bloodhound.svg?style=flat]]
10+Elasticsearch client and query DSL for Haskell
11+==============================================
11
12
12−* Elasticsearch client and query DSL for Haskell
13−
14−** Why?
13+Why?
14+----
15
15
16Search doesn't have to be hard. Let the dog do it.
16Search doesn't have to be hard. Let the dog do it.
17
17
18−** Endorsements
18+Endorsements
19+------------
19
20
20"Bloodhound makes Elasticsearch almost tolerable!" - Almost-gruntled user
21"Bloodhound makes Elasticsearch almost tolerable!" - Almost-gruntled user
21
22
22"ES is a nightmare but Bloodhound at least makes it tolerable." - Same user, later opinion.
23"ES is a nightmare but Bloodhound at least makes it tolerable." - Same user, later opinion.
23
24
24−** Version compatibility
25+Version compatibility
26+---------------------
25
27
26−Elasticsearch >= 1.0 is recommended. Bloodhound mostly works with 0.9.x, but I don't recommend it if you expect everything to work. As of Bloodhound 0.3 all >=1.0 versions of Elasticsearch work.
28+Elasticsearch \>= 1.0 is recommended. Bloodhound mostly works with 0.9.x, but I don't recommend it if you expect everything to work. As of Bloodhound 0.3 all \>=1.0 versions of Elasticsearch work.
27
29
28−Current versions we test against are 1.0.3, 1.1.2, 1.2.3, 1.3.2, and 1.4.0. We also check that GHC 7.6 and 7.8 both build and pass tests. See our [[https://travis-ci.org/bitemyapp/bloodhound][TravisCI]] to learn more.
30+Current versions we test against are 1.0.3, 1.1.2, 1.2.3, 1.3.2, and 1.4.0. We also check that GHC 7.6 and 7.8 both build and pass tests. See our [TravisCI](https://travis-ci.org/bitemyapp/bloodhound) to learn more.
29
31
30−** Stability
32+Stability
33+---------
31
34
32Bloodhound 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.
35Bloodhound 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.
33
36
34−* Hackage page and Haddock documentation
37+Hackage page and Haddock documentation
38+======================================
35
39
36−http://hackage.haskell.org/package/bloodhound
40+<http://hackage.haskell.org/package/bloodhound>
37
41
38−* Examples
42+Examples
43+========
39
44
40−** Index Operations
45+Index Operations
46+----------------
41
47
42−*** Create Index
48+### Create Index
43
49
44−#+BEGIN_SRC haskell
50+``` {.haskell}
45
51
46-- Formatted for use in ghci, so there are "let"s in front of the decls.
52-- Formatted for use in ghci, so there are "let"s in front of the decls.
47
53
@@ -75,22 +81,22 @@ let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
75response <- createIndex testServer defaultIndexSettings testIndex
81response <- createIndex testServer defaultIndexSettings testIndex
76:}
82:}
77
83
78−#+END_SRC
84+```
79
85
80−*** Delete Index
86+### Delete Index
81
87
82−**** Code
88+#### Code
83
89
84−#+BEGIN_SRC haskell
90+``` {.haskell}
85
91
86-- response :: Reply
92-- response :: Reply
87response <- deleteIndex testServer testIndex
93response <- deleteIndex testServer testIndex
88
94
89−#+END_SRC
95+```
90
96
91−**** Example Response
97+#### Example Response
92
98
93−#+BEGIN_SRC haskell
99+``` {.haskell}
94
100
95-- print response if it was a success
101-- print response if it was a success
96Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}
102Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}
@@ -110,21 +116,21 @@ Response {responseStatus = Status {statusCode = 404, statusMessage = "Not Found"
110 , responseCookieJar = CJ {expose = []}
116 , responseCookieJar = CJ {expose = []}
111 , responseClose' = ResponseClose}
117 , responseClose' = ResponseClose}
112
118
113−#+END_SRC
119+```
114
120
115−*** Refresh Index
121+### Refresh Index
116
122
117−**** Note, you *have* to do this if you expect to read what you just wrote
123+#### Note, you **have** to do this if you expect to read what you just wrote
118
124
119−#+BEGIN_SRC haskell
125+``` {.haskell}
120
126
121resp <- refreshIndex testServer testIndex
127resp <- refreshIndex testServer testIndex
122
128
123−#+END_SRC
129+```
124
130
125−**** Example Response
131+#### Example Response
126
132
127−#+BEGIN_SRC haskell
133+``` {.haskell}
128
134
129-- print resp on success
135-- print resp on success
130Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}
136Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}
@@ -135,13 +141,14 @@ Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}
135 , responseCookieJar = CJ {expose = []}
141 , responseCookieJar = CJ {expose = []}
136 , responseClose' = ResponseClose}
142 , responseClose' = ResponseClose}
137
143
138−#+END_SRC
144+```
139
145
140−** Mapping Operations
146+Mapping Operations
147+------------------
141
148
142−*** Create Mapping
149+### Create Mapping
143
150
144−#+BEGIN_SRC haskell
151+``` {.haskell}
145
152
146-- don't forget imports and the like at the top.
153-- don't forget imports and the like at the top.
147
154
@@ -162,21 +169,22 @@ instance ToJSON TweetMapping where
162
169
163resp <- putMapping testServer testIndex testMapping TweetMapping
170resp <- putMapping testServer testIndex testMapping TweetMapping
164
171
165−#+END_SRC
172+```
166
173
167−*** Delete Mapping
174+### Delete Mapping
168
175
169−#+BEGIN_SRC haskell
176+``` {.haskell}
170
177
171resp <- deleteMapping testServer testIndex testMapping
178resp <- deleteMapping testServer testIndex testMapping
172
179
173−#+END_SRC
180+```
174
181
175−** Document Operations
182+Document Operations
183+-------------------
176
184
177−*** Indexing Documents
185+### Indexing Documents
178
186
179−#+BEGIN_SRC haskell
187+``` {.haskell}
180
188
181-- don't forget the imports and derive generic setting for ghci
189-- don't forget the imports and derive generic setting for ghci
182-- at the beginning of the examples.
190-- at the beginning of the examples.
@@ -214,11 +222,11 @@ instance FromJSON Location
214
222
215resp <- indexDocument testServer testIndex testMapping exampleTweet (DocId "1")
223resp <- indexDocument testServer testIndex testMapping exampleTweet (DocId "1")
216
224
217−#+END_SRC
225+```
218
226
219−**** Example Response
227+#### Example Response
220
228
221−#+BEGIN_SRC haskell
229+``` {.haskell}
222
230
223Response {responseStatus =
231Response {responseStatus =
224 Status {statusCode = 200, statusMessage = "OK"}
232 Status {statusCode = 200, statusMessage = "OK"}
@@ -228,19 +236,19 @@ Response {responseStatus =
228 , responseBody = "{\"_index\":\"twitter\",\"_type\":\"tweet\",\"_id\":\"1\",\"_version\":2,\"created\":false}"
236 , responseBody = "{\"_index\":\"twitter\",\"_type\":\"tweet\",\"_id\":\"1\",\"_version\":2,\"created\":false}"
229 , responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}
237 , responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}
230
238
231−#+END_SRC
239+```
232
240
233−*** Deleting Documents
241+### Deleting Documents
234
242
235−#+BEGIN_SRC haskell
243+``` {.haskell}
236
244
237resp <- deleteDocument testServer testIndex testMapping (DocId "1")
245resp <- deleteDocument testServer testIndex testMapping (DocId "1")
238
246
239−#+END_SRC
247+```
240
248
241−*** Getting Documents
249+### Getting Documents
242
250
243−#+BEGIN_SRC haskell
251+``` {.haskell}
244
252
245-- n.b., you'll need the earlier imports. responseBody is from http-conduit
253-- n.b., you'll need the earlier imports. responseBody is from http-conduit
246
254
@@ -281,13 +289,14 @@ Right (Tweet {user = "bitemyapp"
281 , age = 10000
289 , age = 10000
282 , location = Location {lat = 40.12, lon = -71.34}})
290 , location = Location {lat = 40.12, lon = -71.34}})
283
291
284−#+END_SRC
292+```
285
293
286−** Bulk Operations
294+Bulk Operations
295+---------------
287
296
288−*** Bulk create, index
297+### Bulk create, index
289
298
290−#+BEGIN_SRC haskell
299+``` {.haskell}
291
300
292-- don't forget the imports and derive generic setting for ghci
301-- don't forget the imports and derive generic setting for ghci
293-- at the beginning of the examples.
302-- at the beginning of the examples.
@@ -322,11 +331,11 @@ let stream = [firstDoc, secondDoc]
322resp <- bulk testServer stream
331resp <- bulk testServer stream
323:}
332:}
324
333
325−#+END_SRC
334+```
326
335
327−*** Encoding individual bulk API operations
336+### Encoding individual bulk API operations
328
337
329−#+BEGIN_SRC haskell
338+``` {.haskell}
330-- the following functions are exported in Bloodhound so
339-- the following functions are exported in Bloodhound so
331-- you can build up bulk operations yourself
340-- you can build up bulk operations yourself
332encodeBulkOperations :: V.Vector BulkOperation -> L.ByteString
341encodeBulkOperations :: V.Vector BulkOperation -> L.ByteString
@@ -356,15 +365,16 @@ let encodedOperations = encodeBulkOperations stream
356-- bulk :: Server -> V.Vector BulkOperation -> IO Reply
365-- bulk :: Server -> V.Vector BulkOperation -> IO Reply
357_ <- bulk testServer stream
366_ <- bulk testServer stream
358
367
359−#+END_SRC
368+```
360
369
361−** Search
370+Search
371+------
362
372
363−*** Querying
373+### Querying
364
374
365−**** Term Query
375+#### Term Query
366
376
367−#+BEGIN_SRC haskell
377+``` {.haskell}
368
378
369-- exported by the Client module, just defaults some stuff.
379-- exported by the Client module, just defaults some stuff.
370-- mkSearch :: Maybe Query -> Maybe Filter -> Search
380-- mkSearch :: Maybe Query -> Maybe Filter -> Search
@@ -397,31 +407,30 @@ Right [Hit {hitIndex = IndexName "twitter"
397 , age = 10000
407 , age = 10000
398 , location = Location {lat = 40.12, lon = -71.34}}}]
408 , location = Location {lat = 40.12, lon = -71.34}}}]
399
409
400−#+END_SRC
410+```
401
411
402−**** Match Query
412+#### Match Query
403
413
404−#+BEGIN_SRC haskell
414+``` {.haskell}
405
415
406let query = QueryMatchQuery $ mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
416let query = QueryMatchQuery $ mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
407let search = mkSearch (Just query) Nothing
417let search = mkSearch (Just query) Nothing
408
418
409−#+END_SRC
419+```
410−
411
420
412−**** Multi-Match Query
421+#### Multi-Match Query
413
422
414−#+BEGIN_SRC haskell
423+``` {.haskell}
415
424
416let fields = [FieldName "user", FieldName "message"]
425let fields = [FieldName "user", FieldName "message"]
417let query = QueryMultiMatchQuery $ mkMultiMatchQuery fields (QueryString "bitemyapp")
426let query = QueryMultiMatchQuery $ mkMultiMatchQuery fields (QueryString "bitemyapp")
418let search = mkSearch (Just query) Nothing
427let search = mkSearch (Just query) Nothing
419
428
420−#+END_SRC
429+```
421
430
422−**** Bool Query
431+#### Bool Query
423
432
424−#+BEGIN_SRC haskell
433+``` {.haskell}
425
434
426let innerQuery = QueryMatchQuery $
435let innerQuery = QueryMatchQuery $
427 mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
436 mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
@@ -429,11 +438,11 @@ let query = QueryBoolQuery $
429 mkBoolQuery [innerQuery] [] []
438 mkBoolQuery [innerQuery] [] []
430let search = mkSearch (Just query) Nothing
439let search = mkSearch (Just query) Nothing
431
440
432−#+END_SRC
441+```
433
442
434−**** Boosting Query
443+#### Boosting Query
435
444
436−#+BEGIN_SRC haskell
445+``` {.haskell}
437
446
438let posQuery = QueryMatchQuery $
447let posQuery = QueryMatchQuery $
439 mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
448 mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
@@ -442,15 +451,15 @@ let negQuery = QueryMatchQuery $
442let query = QueryBoostingQuery $
451let query = QueryBoostingQuery $
443 BoostingQuery posQuery negQuery (Boost 0.2)
452 BoostingQuery posQuery negQuery (Boost 0.2)
444
453
445−#+END_SRC
454+```
446
455
447−**** Rest of the query/filter types
456+#### Rest of the query/filter types
448
457
449Just follow the pattern you've seen here and check the Hackage API documentation.
458Just follow the pattern you've seen here and check the Hackage API documentation.
450
459
451−*** Sorting
460+### Sorting
452
461
453−#+BEGIN_SRC haskell
462+``` {.haskell}
454
463
455let sortSpec = DefaultSortSpec $ mkSort (FieldName "age") Ascending
464let sortSpec = DefaultSortSpec $ mkSort (FieldName "age") Ascending
456
465
@@ -476,15 +485,15 @@ let sortSpec = DefaultSortSpec $ mkSort (FieldName "age") Ascending
476-- just add more sortspecs to the list if you want tie-breakers.
485-- just add more sortspecs to the list if you want tie-breakers.
477let search = Search Nothing (Just IdentityFilter) (Just [sortSpec]) False 0 10
486let search = Search Nothing (Just IdentityFilter) (Just [sortSpec]) False 0 10
478
487
479−#+END_SRC
488+```
480
489
481−*** Filtering
490+### Filtering
482
491
483−**** And, Not, and Or filters
492+#### And, Not, and Or filters
484
493
485Filters form a monoid and seminearring.
494Filters form a monoid and seminearring.
486
495
487−#+BEGIN_SRC haskell
496+``` {.haskell}
488
497
489instance Monoid Filter where
498instance Monoid Filter where
490 mempty = IdentityFilter
499 mempty = IdentityFilter
@@ -513,11 +522,11 @@ IdentityFilter <||> someOtherFilter
513
522
514NotFilter someOtherFilter False
523NotFilter someOtherFilter False
515
524
516−#+END_SRC
525+```
517
526
518−**** Identity Filter
527+#### Identity Filter
519
528
520−#+BEGIN_SRC haskell
529+``` {.haskell}
521
530
522-- And'ing two Identity
531-- And'ing two Identity
523let queryFilter = IdentityFilter <&&> IdentityFilter
532let queryFilter = IdentityFilter <&&> IdentityFilter
@@ -526,13 +535,13 @@ let search = mkSearch Nothing (Just queryFilter)
526
535
527reply <- searchByType testServer testIndex testMapping search
536reply <- searchByType testServer testIndex testMapping search
528
537
529−#+END_SRC
538+```
530
539
531−**** Boolean Filter
540+#### Boolean Filter
532
541
533Similar to boolean queries.
542Similar to boolean queries.
534
543
535−#+BEGIN_SRC haskell
544+``` {.haskell}
536
545
537-- Will return only items whose "user" field contains the term "bitemyapp"
546-- Will return only items whose "user" field contains the term "bitemyapp"
538let queryFilter = BoolFilter (MustMatch (Term "user" "bitemyapp") False)
547let queryFilter = BoolFilter (MustMatch (Term "user" "bitemyapp") False)
@@ -546,31 +555,31 @@ let queryFilter = BoolFilter (MustNotMatch (Term "user" "bitemyapp") False)
546-- clauses to match can be set using the minimum_should_match parameter.
555-- clauses to match can be set using the minimum_should_match parameter.
547let queryFilter = BoolFilter (ShouldMatch [(Term "user" "bitemyapp")] False)
556let queryFilter = BoolFilter (ShouldMatch [(Term "user" "bitemyapp")] False)
548
557
549−#+END_SRC
558+```
550
559
551−**** Exists Filter
560+#### Exists Filter
552
561
553−#+BEGIN_SRC haskell
562+``` {.haskell}
554
563
555-- Will filter for documents that have the field "user"
564-- Will filter for documents that have the field "user"
556let existsFilter = ExistsFilter (FieldName "user")
565let existsFilter = ExistsFilter (FieldName "user")
557
566
558−#+END_SRC
567+```
559
568
560−**** Geo BoundingBox Filter
569+#### Geo BoundingBox Filter
561
570
562−#+BEGIN_SRC haskell
571+``` {.haskell}
563
572
564-- topLeft and bottomRight
573-- topLeft and bottomRight
565let box = GeoBoundingBox (LatLon 40.73 (-74.1)) (LatLon 40.10 (-71.12))
574let box = GeoBoundingBox (LatLon 40.73 (-74.1)) (LatLon 40.10 (-71.12))
566
575
567let constraint = GeoBoundingBoxConstraint (FieldName "tweet.location") box False GeoFilterMemory
576let constraint = GeoBoundingBoxConstraint (FieldName "tweet.location") box False GeoFilterMemory
568
577
569−#+END_SRC
578+```
570
579
571−**** Geo Distance Filter
580+#### Geo Distance Filter
572
581
573−#+BEGIN_SRC haskell
582+``` {.haskell}
574
583
575let geoPoint = GeoPoint (FieldName "tweet.location") (LatLon 40.12 (-71.34))
584let geoPoint = GeoPoint (FieldName "tweet.location") (LatLon 40.12 (-71.34))
576
585
@@ -585,13 +594,13 @@ let optimizeBbox = OptimizeGeoFilterType GeoFilterMemory
585
594
586let geoFilter = GeoDistanceFilter geoPoint distance SloppyArc optimizeBbox False
595let geoFilter = GeoDistanceFilter geoPoint distance SloppyArc optimizeBbox False
587
596
588−#+END_SRC
597+```
589
598
590−**** Geo Distance Range Filter
599+#### Geo Distance Range Filter
591
600
592Think of a donut and you won't be far off.
601Think of a donut and you won't be far off.
593
602
594−#+BEGIN_SRC haskell
603+``` {.haskell}
595
604
596let geoPoint = GeoPoint (FieldName "tweet.location") (LatLon 40.12 (-71.34))
605let geoPoint = GeoPoint (FieldName "tweet.location") (LatLon 40.12 (-71.34))
597
606
@@ -599,11 +608,11 @@ let distanceRange = DistanceRange (Distance 0.0 Miles) (Distance 10.0 Miles)
599
608
600let geoFilter = GeoDistanceRangeFilter geoPoint distanceRange
609let geoFilter = GeoDistanceRangeFilter geoPoint distanceRange
601
610
602−#+END_SRC
611+```
603
612
604−**** Geo Polygon Filter
613+#### Geo Polygon Filter
605
614
606−#+BEGIN_SRC haskell
615+``` {.haskell}
607
616
608-- I think I drew a square here.
617-- I think I drew a square here.
609let points = [LatLon 40.0 (-70.00),
618let points = [LatLon 40.0 (-70.00),
@@ -613,22 +622,22 @@ let points = [LatLon 40.0 (-70.00),
613
622
614let geoFilter = GeoPolygonFilter (FieldName "tweet.location") points
623let geoFilter = GeoPolygonFilter (FieldName "tweet.location") points
615
624
616−#+END_SRC
625+```
617
626
618−**** Document IDs filter
627+#### Document IDs filter
619
628
620−#+BEGIN_SRC haskell
629+``` {.haskell}
621
630
622-- takes a mapping name and a list of DocIds
631-- takes a mapping name and a list of DocIds
623IdsFilter (MappingName "tweet") [DocId "1"]
632IdsFilter (MappingName "tweet") [DocId "1"]
624
633
625−#+END_SRC
634+```
626
635
627−**** Range Filter
636+#### Range Filter
628
637
629−***** Full Range
638+##### Full Range
630
639
631−#+BEGIN_SRC haskell
640+``` {.haskell}
632
641
633-- RangeFilter :: FieldName
642-- RangeFilter :: FieldName
634-- -> Either HalfRange Range
643-- -> Either HalfRange Range
@@ -639,21 +648,21 @@ let filter = RangeFilter (FieldName "age")
639 (Right (RangeLtGt (LessThan 100000.0) (GreaterThan 1000.0)))
648 (Right (RangeLtGt (LessThan 100000.0) (GreaterThan 1000.0)))
640 RangeExecutionIndex False
649 RangeExecutionIndex False
641
650
642−#+END_SRC
651+```
643
652
644−***** Half Range
653+##### Half Range
645
654
646−#+BEGIN_SRC haskell
655+``` {.haskell}
647
656
648let filter = RangeFilter (FieldName "age")
657let filter = RangeFilter (FieldName "age")
649 (Left (HalfRangeLt (LessThan 100000.0)))
658 (Left (HalfRangeLt (LessThan 100000.0)))
650 RangeExecutionIndex False
659 RangeExecutionIndex False
651
660
652−#+END_SRC
661+```
653
662
654−**** Regexp Filter
663+#### Regexp Filter
655
664
656−#+BEGIN_SRC haskell
665+``` {.haskell}
657
666
658-- RegexpFilter
667-- RegexpFilter
659-- :: FieldName
668-- :: FieldName
@@ -678,47 +687,48 @@ let filter = RegexpFilter (FieldName "user") (Regexp "bite.*app")
678-- | Intersection
687-- | Intersection
679-- | Interval deriving (Eq, Show)
688-- | Interval deriving (Eq, Show)
680
689
681−#+END_SRC
690+```
691+
692+### Aggregations
693+
694+#### Adding aggregations to search
682
695
683−*** Aggregations
684−**** Adding aggregations to search
685Aggregations can now be added to search queries, or made on their own.
696Aggregations can now be added to search queries, or made on their own.
697+
686−#+BEGIN_SRC haskell
698+``` {.haskell}
687type Aggregations = M.Map Text Aggregation
699type Aggregations = M.Map Text Aggregation
688data Aggregation
700data Aggregation
689 = TermsAgg TermsAggregation
701 = TermsAgg TermsAggregation
690 | DateHistogramAgg DateHistogramAggregation
702 | DateHistogramAgg DateHistogramAggregation
691−#+END_SRC
703+```
692
704
693−For convenience, ```mkAggregations``` exists, that will create an
705+For convenience, \`\`\`mkAggregations\`\`\` exists, that will create an \`\`\`Aggregations\`\`\` with the aggregation provided.
694−```Aggregations``` with the aggregation provided.
695
706
696For example:
707For example:
708+
697−#+BEGIN_SRC haskell
709+``` {.haskell}
698 let a = mkAggregations "users" $ TermsAgg $ mkTermsAggregation "user"
710 let a = mkAggregations "users" $ TermsAgg $ mkTermsAggregation "user"
699 let search = mkAggregateSearch Nothing a
711 let search = mkAggregateSearch Nothing a
700−#+END_SRC
712+```
701
713
702−Aggregations can be added to an existing search, using the
714+Aggregations can be added to an existing search, using the \`\`\`aggBody\`\`\` field
703−```aggBody``` field
704
715
705−#+BEGIN_SRC haskell
716+``` {.haskell}
706 let search = mkSearch (Just (MatchAllQuery Nothing)) Nothing
717 let search = mkSearch (Just (MatchAllQuery Nothing)) Nothing
707 let search' = search {aggBody = Just a}
718 let search' = search {aggBody = Just a}
708−#+END_SRC
719+```
709
720
710−Since the ```Aggregations``` structure is just a Map Text
711−Aggregation, M.insert can be used to add additional aggregations.
721+Since the \`\`\`Aggregations\`\`\` structure is just a Map Text Aggregation, M.insert can be used to add additional aggregations.
712
722
713−#+BEGIN_SRC haskell
723+``` {.haskell}
714 let a' = M.insert "age" (TermsAgg $ mkTermsAggregation "age") a
724 let a' = M.insert "age" (TermsAgg $ mkTermsAggregation "age") a
715−#+END_SRC
725+```
716
726
717−**** Extracting aggregations from results
727+#### Extracting aggregations from results
718−Aggregations are part of the reply structure of every search, in the
719−form of ~Maybe AggregationResults~
720
728
729+Aggregations are part of the reply structure of every search, in the form of
730+
721−#+BEGIN_SRC haskell
731+``` {.haskell}
722-- Lift decode and response body to be in the IO monad.
732-- Lift decode and response body to be in the IO monad.
723let decode' = liftM decode
733let decode' = liftM decode
724let responseBody' = liftM responseBody
734let responseBody' = liftM responseBody
@@ -730,25 +740,24 @@ let response = decode' $ responseBody' reply :: IO (Maybe (SearchResult Tweet))
730let terms = do { response' <- response; return $ response' >>= aggregations >>= toTerms "users" }
740let terms = do { response' <- response; return $ response' >>= aggregations >>= toTerms "users" }
731terms
741terms
732Just (Bucket {buckets = [TermsResult {termKey = "bitemyapp", termsDocCount = 1, termsAggs = Nothing}]})
742Just (Bucket {buckets = [TermsResult {termKey = "bitemyapp", termsDocCount = 1, termsAggs = Nothing}]})
733−#+END_SRC
743+```
734
744
735−Note that bucket aggregation results, such as the TermsResult is a
745+Note that bucket aggregation results, such as the TermsResult is a member of the type class :
736−member of the type class ~BucketAggregation~:
737
746
738−#+BEGIN_SRC haskell
747+``` {.haskell}
739class BucketAggregation a where
748class BucketAggregation a where
740 key :: a -> Text
749 key :: a -> Text
741 docCount :: a -> Int
750 docCount :: a -> Int
742 aggs :: a -> Maybe AggregationResults
751 aggs :: a -> Maybe AggregationResults
752+```
753+
743−#+END_SRC haskell
754+haskell
755+
756+You can use the function to get any nested results, if there were any. For example, if there were a nested terms aggregation keyed to "age" in a TermsResult named , you would call
744
757
745−You can use the ~aggs~ function to get any nested results, if
758+#### Terms Aggregation
746−there were any. For example, if there were a nested terms
747−aggregation keyed to "age" in a TermsResult named ~termresult~, you would call ~aggs termresult >>=
748−toTerms "age"~
749
759
750−**** Terms Aggregation
751−#+BEGIN_SRC haskell
760+``` {.haskell}
752data TermsAggregation
761data TermsAggregation
753 = TermsAggregation {term :: Either Text Text,
762 = TermsAggregation {term :: Either Text Text,
754 termInclude :: Maybe TermInclusion,
763 termInclude :: Maybe TermInclusion,
@@ -760,30 +769,27 @@ data TermsAggregation
760 termCollectMode :: Maybe CollectionMode,
769 termCollectMode :: Maybe CollectionMode,
761 termExecutionHint :: Maybe ExecutionHint,
770 termExecutionHint :: Maybe ExecutionHint,
762 termAggs :: Maybe Aggregations}
771 termAggs :: Maybe Aggregations}
763−#+END_SRC
772+```
764
773
765−Term Aggregations have two factory functions,
774+Term Aggregations have two factory functions, , and , and can be used as follows:
766−~mkTermsAggregation~, and ~mkTermsScriptAggregation~, and can
767−be used as follows:
768
775
769−#+BEGIN_SRC haskell
776+``` {.haskell}
770let ta = TermsAgg $ mkTermsAggregation "user"
777let ta = TermsAgg $ mkTermsAggregation "user"
771−#+END_SRC
778+```
772
779
773−There are of course other options that can be added to a Terms
780+There are of course other options that can be added to a Terms Aggregation, such as the collection mode:
774−Aggregation, such as the collection mode:
781+
775−#+BEGIN_SRC haskell
782+``` {.haskell}
776let ta = mkTermsAggregation "user"
783let ta = mkTermsAggregation "user"
777let ta' = ta { termCollectMode = Just BreadthFirst }
784let ta' = ta { termCollectMode = Just BreadthFirst }
778let ta'' = TermsAgg ta'
785let ta'' = TermsAgg ta'
779−#+END_SRC
786+```
780
787
781−For more documentation on how the Terms Aggregation works, see
782−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html
788+For more documentation on how the Terms Aggregation works, see <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html>
783
789
784−**** Date Histogram Aggregation
790+#### Date Histogram Aggregation
785
791
786−#+BEGIN_SRC haskell
792+``` {.haskell}
787data DateHistogramAggregation
793data DateHistogramAggregation
788 = DateHistogramAggregation {dateField :: FieldName,
794 = DateHistogramAggregation {dateField :: FieldName,
789 dateInterval :: Interval,
795 dateInterval :: Interval,
@@ -793,116 +799,132 @@ data DateHistogramAggregation
793 datePreOffset :: Maybe Text,
799 datePreOffset :: Maybe Text,
794 datePostOffset :: Maybe Text,
800 datePostOffset :: Maybe Text,
795 dateAggs :: Maybe Aggregations}
801 dateAggs :: Maybe Aggregations}
802+```
803+
796−#+END_SRC haskell
804+haskell
797
805
798−The Date Histogram Aggregation works much the same as the Terms
806+The Date Histogram Aggregation works much the same as the Terms Aggregation.
799−Aggregation.
800
807
801−Relevant functions include ~mkDateHistogram~, and ~toDateHistogram~
808+Relevant functions include , and
802
809
803−#+BEGIN_SRC haskell
810+``` {.haskell}
804let dh = DateHistogramAgg (mkDateHistogram (FieldName "postDate") Minute)
811let dh = DateHistogramAgg (mkDateHistogram (FieldName "postDate") Minute)
805−#+END_SRC
812+```
806
813
807−Date histograms also accept a ~FractionalInterval~:
814+Date histograms also accept a :
808
815
809−#+BEGIN_SRC haskell
816+``` {.haskell}
810FractionalInterval :: Float -> TimeInterval -> Interval
817FractionalInterval :: Float -> TimeInterval -> Interval
811-- TimeInterval is the following:
818-- TimeInterval is the following:
812data TimeInterval = Weeks | Days | Hours | Minutes | Seconds
819data TimeInterval = Weeks | Days | Hours | Minutes | Seconds
813−#+END_SRC
820+```
814
821
815It can be used as follows:
822It can be used as follows:
816
823
817−#+BEGIN_SRC haskell
824+``` {.haskell}
818let dh = DateHistogramAgg (mkDateHistogram (FieldName "postDate") (FractionalInterval 1.5 Minutes))
825let dh = DateHistogramAgg (mkDateHistogram (FieldName "postDate") (FractionalInterval 1.5 Minutes))
819−#+END_SRC
826+```
820
827
821−The ~DateHistogramResult~ is defined as:
828+The is defined as:
822
829
823−#+BEGIN_SRC haskell
830+``` {.haskell}
824data DateHistogramResult
831data DateHistogramResult
825 = DateHistogramResult {dateKey :: Int,
832 = DateHistogramResult {dateKey :: Int,
826 dateKeyStr :: Maybe Text,
833 dateKeyStr :: Maybe Text,
827 dateDocCount :: Int,
834 dateDocCount :: Int,
828 dateHistogramAggs :: Maybe AggregationResults}
835 dateHistogramAggs :: Maybe AggregationResults}
829−#+END_SRC
836+```
830
837
831−It is an instance of ~BucketAggregation~, and can have nested
838+It is an instance of , and can have nested aggregations in each bucket.
832−aggregations in each bucket.
833
839
834−Buckets can be extracted from a ~AggregationResult~ using
840+Buckets can be extracted from a using
835−~toDateHistogram name~
836
841
837−For more information on the Date Histogram Aggregation, see:
838−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html
842+For more information on the Date Histogram Aggregation, see: <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html>
839
843
840−* Possible future functionality
844+Possible future functionality
845+=============================
841
846
842−** Span Queries
847+Span Queries
848+------------
843
849
844−Beginning here: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html
850+Beginning here: <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html>
845
851
846−** Function Score Query
852+Function Score Query
853+--------------------
847
854
848−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
855+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html>
849
856
850−** Node discovery and failover
857+Node discovery and failover
858+---------------------------
851
859
852Might require TCP support.
860Might require TCP support.
853
861
854−** Support for TCP access to Elasticsearch
862+Support for TCP access to Elasticsearch
863+---------------------------------------
855
864
856Pretend to be a transport client?
865Pretend to be a transport client?
857
866
858−** Bulk cluster-join merge
867+Bulk cluster-join merge
868+-----------------------
859
869
860Might require making a lucene index on disk with the appropriate format.
870Might require making a lucene index on disk with the appropriate format.
861
871
862−** GeoShapeQuery
872+GeoShapeQuery
873+-------------
863
874
864−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html
875+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html>
865
876
866−** GeoShapeFilter
877+GeoShapeFilter
878+--------------
867
879
868−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html
880+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html>
869
881
870−** Geohash cell filter
882+Geohash cell filter
883+-------------------
871
884
872−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geohash-cell-filter.html
885+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geohash-cell-filter.html>
873
886
874−** HasChild Filter
887+HasChild Filter
888+---------------
875
889
876−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html
890+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html>
877
891
878−** HasParent Filter
892+HasParent Filter
893+----------------
879
894
880−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html
895+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html>
881
896
882−** Indices Filter
897+Indices Filter
898+--------------
883
899
884−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-indices-filter.html
900+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-indices-filter.html>
885
901
886−** Query Filter
902+Query Filter
903+------------
887
904
888−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html
905+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html>
889
906
890−** Script based sorting
907+Script based sorting
908+--------------------
891
909
892−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_script_based_sorting
910+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_script_based_sorting>
893
911
894−** Collapsing redundantly nested and/or structures
912+Collapsing redundantly nested and/or structures
913+-----------------------------------------------
895
914
896The Seminearring instance, if deeply nested can possibly produce nested structure that is redundant. Depending on how this affects ES perforamnce, reducing this structure might be valuable.
915The Seminearring instance, if deeply nested can possibly produce nested structure that is redundant. Depending on how this affects ES perforamnce, reducing this structure might be valuable.
897
916
898−** Runtime checking for cycles in data structures
917+Runtime checking for cycles in data structures
918+----------------------------------------------
919+
920+check for n \> 1 occurrences in DFS:
899
921
900−check for n > 1 occurrences in DFS:
922+<http://hackage.haskell.org/package/stable-maps-0.0.5/docs/System-Mem-StableName-Dynamic.html>
901
923
902−http://hackage.haskell.org/package/stable-maps-0.0.5/docs/System-Mem-StableName-Dynamic.html
924+<http://hackage.haskell.org/package/stable-maps-0.0.5/docs/System-Mem-StableName-Dynamic-Map.html>
903
925
904−http://hackage.haskell.org/package/stable-maps-0.0.5/docs/System-Mem-StableName-Dynamic-Map.html
926+Photo Origin
927+============
905
928
906−* Photo Origin
929+Photo from HA! Designs: <https://www.flickr.com/photos/hadesigns/>
907
930
908−Photo from HA! Designs: https://www.flickr.com/photos/hadesigns/