@@ -21,15 +21,18 @@ module Database.Bloodhound.Client
2121 , mkShardCount
2222 , mkReplicaCount
2323 , getStatus
24+ , encodeBulkOperations
25+ , encodeBulkOperation
2426 )
2527 where
2628
2729import Data.Aeson
2830import qualified Data.ByteString.Lazy.Char8 as L
2931import Data.ByteString.Builder
30−import Data.List (foldl', intercalate, intersperse)
32+import Data.List (intercalate)
3133import Data.Maybe (fromMaybe)
3234import Data.Text (Text)
35+import qualified Data.Vector as V
3336import Network.HTTP.Client
3437import qualified Network.HTTP.Types.Method as NHTM
3538import qualified Network.HTTP.Types.Status as NHTS
@@ -167,52 +170,53 @@ deleteDocument (Server server) (IndexName indexName)
167170 (MappingName mappingName) (DocId docId) =
168171 delete $ joinPath [server, indexName, mappingName, docId]
169172
170−bulk :: Server -> [BulkOperation] -> IO Reply
173+bulk :: Server -> V.Vector BulkOperation -> IO Reply
171174bulk (Server server) bulkOps = post url body where
172175 url = joinPath [server, "_bulk"]
173− body = Just $ collapseStream bulkOps
176+ body = Just $ encodeBulkOperations bulkOps
174177
175−collapseStream :: [BulkOperation] -> L.ByteString
176−collapseStream stream = collapsed where
177− blobs = intersperse "\n" $ concat $ fmap getStreamChunk stream
178+encodeBulkOperations :: V.Vector BulkOperation -> L.ByteString
179+encodeBulkOperations stream = collapsed where
180+ blobs = fmap encodeBulkOperation stream
178181 mashedTaters = mash (mempty :: Builder) blobs
179182 collapsed = toLazyByteString $ mappend mashedTaters (byteString "\n")
180183
181−mash :: Builder -> [L.ByteString] -> Builder
182−mash = foldl' (\b x -> mappend b (lazyByteString x))
184+mash :: Builder -> V.Vector L.ByteString -> Builder
185+mash = V.foldl' (\b x -> b `mappend` "\n" `mappend` (lazyByteString x))
183186
184−mkMetadataValue :: Text -> String -> String -> String -> Value
185−mkMetadataValue operation indexName mappingName docId =
187+mkBulkStreamValue :: Text -> String -> String -> String -> Value
188+mkBulkStreamValue operation indexName mappingName docId =
186189 object [operation .=
187190 object [ "_index" .= indexName
188191 , "_type" .= mappingName
189192 , "_id" .= docId]]
190193
191−getStreamChunk :: BulkOperation -> [L.ByteString]
192−getStreamChunk (BulkIndex (IndexName indexName)
194+encodeBulkOperation :: BulkOperation -> L.ByteString
195+encodeBulkOperation (BulkIndex (IndexName indexName)
193196 (MappingName mappingName)
194− (DocId docId) value) = blob where
195− metadata = mkMetadataValue "index" indexName mappingName docId
196− blob = [encode metadata, encode value]
197+ (DocId docId) value) = blob
198+ where metadata = mkBulkStreamValue "index" indexName mappingName docId
199+ blob = encode metadata `mappend` "\n" `mappend` encode value
197200
198−getStreamChunk (BulkCreate (IndexName indexName)
201+encodeBulkOperation (BulkCreate (IndexName indexName)
199202 (MappingName mappingName)
200− (DocId docId) value) = blob where
201− metadata = mkMetadataValue "create" indexName mappingName docId
202− blob = [encode metadata, encode value]
203+ (DocId docId) value) = blob
204+ where metadata = mkBulkStreamValue "create" indexName mappingName docId
205+ blob = encode metadata `mappend` "\n" `mappend` encode value
203206
204−getStreamChunk (BulkDelete (IndexName indexName)
207+encodeBulkOperation (BulkDelete (IndexName indexName)
205208 (MappingName mappingName)
206− (DocId docId)) = blob where
207− metadata = mkMetadataValue "delete" indexName mappingName docId
208− blob = [encode metadata]
209+ (DocId docId)) = blob
210+ where metadata = mkBulkStreamValue "delete" indexName mappingName docId
211+ blob = encode metadata
209212
210−getStreamChunk (BulkUpdate (IndexName indexName)
213+encodeBulkOperation (BulkUpdate (IndexName indexName)
211214 (MappingName mappingName)
212− (DocId docId) value) = blob where
213− metadata = mkMetadataValue "update" indexName mappingName docId
214− doc = object ["doc" .= value]
215− blob = [encode metadata, encode doc]
215+ (DocId docId) value) = blob
216+ where metadata = mkBulkStreamValue "update" indexName mappingName docId
217+ doc = object ["doc" .= value]
218+ blob = encode metadata `mappend` "\n" `mappend` encode doc
219+
216220
217221getDocument :: Server -> IndexName -> MappingName
218222 -> DocId -> IO Reply