git.iko.soy/typeable/bloodhound
on master help sign in
Add search after functionality
4967c62Shulhi Sapli
src/Database/V5/Bloodhound/Client.hs+16−16
@@ -523,13 +523,13 @@ createIndex indexSettings (IndexName indexName) =
523createIndexWith :: MonadBH m
523createIndexWith :: MonadBH m
524 => [UpdatableIndexSetting]
524 => [UpdatableIndexSetting]
525 -> Int -- ^ shard count
525 -> Int -- ^ shard count
526− -> IndexName
526+ -> IndexName
527 -> m Reply
527 -> m Reply
528createIndexWith updates shards (IndexName indexName) =
528createIndexWith updates shards (IndexName indexName) =
529 bindM2 put url (return (Just body))
529 bindM2 put url (return (Just body))
530 where url = joinPath [indexName]
530 where url = joinPath [indexName]
531 body = encode $ object
531 body = encode $ object
532− ["settings" .= deepMerge
532+ ["settings" .= deepMerge
533 ( HM.singleton "index.number_of_shards" (toJSON shards) :
533 ( HM.singleton "index.number_of_shards" (toJSON shards) :
534 [u | Object u <- toJSON <$> updates]
534 [u | Object u <- toJSON <$> updates]
535 )
535 )
@@ -575,8 +575,8 @@ getIndexSettings (IndexName indexName) =
575 where
575 where
576 url = joinPath [indexName, "_settings"]
576 url = joinPath [indexName, "_settings"]
577
577
578−-- | 'forceMergeIndex'
578+-- | 'forceMergeIndex'
579−--
579+--
580-- The force merge API allows to force merging of one or more indices through
580-- The force merge API allows to force merging of one or more indices through
581-- an API. The merge relates to the number of segments a Lucene index holds
581-- an API. The merge relates to the number of segments a Lucene index holds
582-- within each shard. The force merge operation allows to reduce the number of
582-- within each shard. The force merge operation allows to reduce the number of
@@ -1035,10 +1035,10 @@ searchByType (IndexName indexName)
1035-- search results. Note that the search is put into 'SearchTypeScan'
1035-- search results. Note that the search is put into 'SearchTypeScan'
1036-- mode and thus results will not be sorted. Combine this with
1036-- mode and thus results will not be sorted. Combine this with
1037-- 'advanceScroll' to efficiently stream through the full result set
1037-- 'advanceScroll' to efficiently stream through the full result set
1038−getInitialScroll ::
1038+getInitialScroll ::
1039− (FromJSON a, MonadThrow m, MonadBH m) => IndexName ->
1039+ (FromJSON a, MonadThrow m, MonadBH m) => IndexName ->
1040− MappingName ->
1040+ MappingName ->
1041− Search ->
1041+ Search ->
1042 m (Either EsError (SearchResult a))
1042 m (Either EsError (SearchResult a))
1043getInitialScroll (IndexName indexName) (MappingName mappingName) search' = do
1043getInitialScroll (IndexName indexName) (MappingName mappingName) search' = do
1044 let url = addQuery params <$> joinPath [indexName, mappingName, "_search"]
1044 let url = addQuery params <$> joinPath [indexName, mappingName, "_search"]
@@ -1063,7 +1063,7 @@ getInitialSortedScroll (IndexName indexName) (MappingName mappingName) search =
1063 resp' <- bindM2 dispatchSearch url (return search)
1063 resp' <- bindM2 dispatchSearch url (return search)
1064 parseEsResponse resp'
1064 parseEsResponse resp'
1065
1065
1066−scroll' :: (FromJSON a, MonadBH m, MonadThrow m) => Maybe ScrollId ->
1066+scroll' :: (FromJSON a, MonadBH m, MonadThrow m) => Maybe ScrollId ->
1067 m ([Hit a], Maybe ScrollId)
1067 m ([Hit a], Maybe ScrollId)
1068scroll' Nothing = return ([], Nothing)
1068scroll' Nothing = return ([], Nothing)
1069scroll' (Just sid) = do
1069scroll' (Just sid) = do
@@ -1090,13 +1090,13 @@ advanceScroll (ScrollId sid) scroll = do
1090 where scrollTime = showText secs <> "s"
1090 where scrollTime = showText secs <> "s"
1091 secs :: Integer
1091 secs :: Integer
1092 secs = round scroll
1092 secs = round scroll
1093−
1093+
1094 scrollObject = object [ "scroll" .= scrollTime
1094 scrollObject = object [ "scroll" .= scrollTime
1095 , "scroll_id" .= sid
1095 , "scroll_id" .= sid
1096 ]
1096 ]
1097
1097
1098−simpleAccumulator ::
1098+simpleAccumulator ::
1099− (FromJSON a, MonadBH m, MonadThrow m) =>
1099+ (FromJSON a, MonadBH m, MonadThrow m) =>
1100 [Hit a] ->
1100 [Hit a] ->
1101 ([Hit a], Maybe ScrollId) ->
1101 ([Hit a], Maybe ScrollId) ->
1102 m ([Hit a], Maybe ScrollId)
1102 m ([Hit a], Maybe ScrollId)
@@ -1134,9 +1134,9 @@ scanSearch indexName mappingName search = do
1134--
1134--
1135-- >>> let query = TermQuery (Term "user" "bitemyapp") Nothing
1135-- >>> let query = TermQuery (Term "user" "bitemyapp") Nothing
1136-- >>> mkSearch (Just query) Nothing
1136-- >>> mkSearch (Just query) Nothing
1137−-- Search {queryBody = Just (TermQuery (Term {termField = "user", termValue = "bitemyapp"}) Nothing), filterBody = Nothing, sortBody = Nothing, aggBody = Nothing, highlight = Nothing, trackSortScores = False, from = From 0, size = Size 10, searchType = SearchTypeQueryThenFetch, fields = Nothing, source = Nothing}
1137+-- Search {queryBody = Just (TermQuery (Term {termField = "user", termValue = "bitemyapp"}) Nothing), filterBody = Nothing, searchAfterKey = Nothing, sortBody = Nothing, aggBody = Nothing, highlight = Nothing, trackSortScores = False, from = From 0, size = Size 10, searchType = SearchTypeQueryThenFetch, fields = Nothing, source = Nothing}
1138mkSearch :: Maybe Query -> Maybe Filter -> Search
1138mkSearch :: Maybe Query -> Maybe Filter -> Search
1139−mkSearch query filter = Search query filter Nothing Nothing Nothing False (From 0) (Size 10) SearchTypeQueryThenFetch Nothing Nothing Nothing Nothing
1139+mkSearch query filter = Search query filter Nothing Nothing Nothing False (From 0) (Size 10) SearchTypeQueryThenFetch Nothing Nothing Nothing Nothing Nothing
1140
1140
1141-- | 'mkAggregateSearch' is a helper function that defaults everything in a 'Search' except for
1141-- | 'mkAggregateSearch' is a helper function that defaults everything in a 'Search' except for
1142-- the 'Query' and the 'Aggregation'.
1142-- the 'Query' and the 'Aggregation'.
@@ -1146,7 +1146,7 @@ mkSearch query filter = Search query filter Nothing Nothing Nothing False (From
1146-- TermsAgg (TermsAggregation {term = Left "user", termInclude = Nothing, termExclude = Nothing, termOrder = Nothing, termMinDocCount = Nothing, termSize = Nothing, termShardSize = Nothing, termCollectMode = Just BreadthFirst, termExecutionHint = Nothing, termAggs = Nothing})
1146-- TermsAgg (TermsAggregation {term = Left "user", termInclude = Nothing, termExclude = Nothing, termOrder = Nothing, termMinDocCount = Nothing, termSize = Nothing, termShardSize = Nothing, termCollectMode = Just BreadthFirst, termExecutionHint = Nothing, termAggs = Nothing})
1147-- >>> let myAggregation = mkAggregateSearch Nothing $ mkAggregations "users" terms
1147-- >>> let myAggregation = mkAggregateSearch Nothing $ mkAggregations "users" terms
1148mkAggregateSearch :: Maybe Query -> Aggregations -> Search
1148mkAggregateSearch :: Maybe Query -> Aggregations -> Search
1149−mkAggregateSearch query mkSearchAggs = Search query Nothing Nothing (Just mkSearchAggs) Nothing False (From 0) (Size 0) SearchTypeQueryThenFetch Nothing Nothing Nothing Nothing
1149+mkAggregateSearch query mkSearchAggs = Search query Nothing Nothing (Just mkSearchAggs) Nothing False (From 0) (Size 0) SearchTypeQueryThenFetch Nothing Nothing Nothing Nothing Nothing
1150
1150
1151-- | 'mkHighlightSearch' is a helper function that defaults everything in a 'Search' except for
1151-- | 'mkHighlightSearch' is a helper function that defaults everything in a 'Search' except for
1152-- the 'Query' and the 'Aggregation'.
1152-- the 'Query' and the 'Aggregation'.
@@ -1155,7 +1155,7 @@ mkAggregateSearch query mkSearchAggs = Search query Nothing Nothing (Just mkSear
1155-- >>> let testHighlight = Highlights Nothing [FieldHighlight (FieldName "message") Nothing]
1155-- >>> let testHighlight = Highlights Nothing [FieldHighlight (FieldName "message") Nothing]
1156-- >>> let search = mkHighlightSearch (Just query) testHighlight
1156-- >>> let search = mkHighlightSearch (Just query) testHighlight
1157mkHighlightSearch :: Maybe Query -> Highlights -> Search
1157mkHighlightSearch :: Maybe Query -> Highlights -> Search
1158−mkHighlightSearch query searchHighlights = Search query Nothing Nothing Nothing (Just searchHighlights) False (From 0) (Size 10) SearchTypeQueryThenFetch Nothing Nothing Nothing Nothing
1158+mkHighlightSearch query searchHighlights = Search query Nothing Nothing Nothing (Just searchHighlights) False (From 0) (Size 10) SearchTypeQueryThenFetch Nothing Nothing Nothing Nothing Nothing
1159
1159
1160-- | 'pageSearch' is a helper function that takes a search and assigns the from
1160-- | 'pageSearch' is a helper function that takes a search and assigns the from
1161-- and size fields for the search. The from parameter defines the offset
1161-- and size fields for the search. The from parameter defines the offset
src/Database/V5/Bloodhound/Internal/Aggregation.hs+4
@@ -6,6 +6,7 @@ module Database.V5.Bloodhound.Internal.Aggregation where
6
6
7import Bloodhound.Import
7import Bloodhound.Import
8
8
9+import qualified Data.Aeson as Aeson
9import qualified Data.HashMap.Strict as HM
10import qualified Data.HashMap.Strict as HM
10import qualified Data.Map.Strict as M
11import qualified Data.Map.Strict as M
11import qualified Data.Text as T
12import qualified Data.Text as T
@@ -445,6 +446,7 @@ instance Monoid (SearchHits a) where
445 mempty = SearchHits 0 Nothing mempty
446 mempty = SearchHits 0 Nothing mempty
446 mappend = (<>)
447 mappend = (<>)
447
448
449+type SearchAfterKey = [Aeson.Value]
448
450
449data Hit a =
451data Hit a =
450 Hit { hitIndex :: IndexName
452 Hit { hitIndex :: IndexName
@@ -452,6 +454,7 @@ data Hit a =
452 , hitDocId :: DocId
454 , hitDocId :: DocId
453 , hitScore :: Score
455 , hitScore :: Score
454 , hitSource :: Maybe a
456 , hitSource :: Maybe a
457+ , hitSort :: Maybe SearchAfterKey
455 , hitFields :: Maybe HitFields
458 , hitFields :: Maybe HitFields
456 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
459 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
457
460
@@ -462,6 +465,7 @@ instance (FromJSON a) => FromJSON (Hit a) where
462 v .: "_id" <*>
465 v .: "_id" <*>
463 v .: "_score" <*>
466 v .: "_score" <*>
464 v .:? "_source" <*>
467 v .:? "_source" <*>
468+ v .:? "sort" <*>
465 v .:? "fields" <*>
469 v .:? "fields" <*>
466 v .:? "highlight"
470 v .:? "highlight"
467 parseJSON _ = empty
471 parseJSON _ = empty
src/Database/V5/Bloodhound/Types.hs+5−2
@@ -382,6 +382,7 @@ module Database.V5.Bloodhound.Types
382 , DateMathUnit(..)
382 , DateMathUnit(..)
383 , TopHitsAggregation(..)
383 , TopHitsAggregation(..)
384 , StatisticsAggregation(..)
384 , StatisticsAggregation(..)
385+ , SearchAfterKey
385
386
386 , Highlights(..)
387 , Highlights(..)
387 , FieldHighlight(..)
388 , FieldHighlight(..)
@@ -413,7 +414,7 @@ module Database.V5.Bloodhound.Types
413 , TokenChar(..)
414 , TokenChar(..)
414 , Shingle(..)
415 , Shingle(..)
415 , Language(..)
416 , Language(..)
416− ) where
417+ ) where
417
418
418import Bloodhound.Import
419import Bloodhound.Import
419
420
@@ -444,6 +445,7 @@ data Search = Search { queryBody :: Maybe Query
444 , from :: From
445 , from :: From
445 , size :: Size
446 , size :: Size
446 , searchType :: SearchType
447 , searchType :: SearchType
448+ , searchAfterKey :: Maybe SearchAfterKey
447 , fields :: Maybe [FieldName]
449 , fields :: Maybe [FieldName]
448 , scriptFields :: Maybe ScriptFields
450 , scriptFields :: Maybe ScriptFields
449 , source :: Maybe Source
451 , source :: Maybe Source
@@ -453,7 +455,7 @@ data Search = Search { queryBody :: Maybe Query
453
455
454instance ToJSON Search where
456instance ToJSON Search where
455 toJSON (Search mquery sFilter sort searchAggs
457 toJSON (Search mquery sFilter sort searchAggs
456− highlight sTrackSortScores sFrom sSize _ sFields
458+ highlight sTrackSortScores sFrom sSize _ sAfter sFields
457 sScriptFields sSource sSuggest) =
459 sScriptFields sSource sSuggest) =
458 omitNulls [ "query" .= query'
460 omitNulls [ "query" .= query'
459 , "sort" .= sort
461 , "sort" .= sort
@@ -462,6 +464,7 @@ instance ToJSON Search where
462 , "from" .= sFrom
464 , "from" .= sFrom
463 , "size" .= sSize
465 , "size" .= sSize
464 , "track_scores" .= sTrackSortScores
466 , "track_scores" .= sTrackSortScores
467+ , "search_after" .= sAfter
465 , "fields" .= sFields
468 , "fields" .= sFields
466 , "script_fields" .= sScriptFields
469 , "script_fields" .= sScriptFields
467 , "_source" .= sSource
470 , "_source" .= sSource