ductile
Version:
Elasticsearch Bulk Loader
84 lines (74 loc) • 1.93 kB
text/coffeescript
###*
# Expose an elasticsearch query that returns hits or docs as a stream of hits or docs.
#
# Expect the query to be a JSON object where the from property defines the offset
# and the limit defines the page size.
# Expect the client to return a parsed JSON.
###
###*
# @param queryExec an executable query functions that takes 2 arguments: the offset and a callback.
###
ReadableHits = (queryExec, parseHit) ->
if !(this instanceof ReadableHits)
return new ReadableHits(queryExec)
Readable.call this, objectMode: true
@queryExec = queryExec
@total = -1
@from = 0
@_next = true
# current iteration through the page
@_hits = []
@_current = 0
@parseHit = parseHit or identity
return
identity = (hit) ->
hit
'use strict'
Readable = require('stream').Readable
module.exports = ReadableHits
ReadableHits.prototype = Object.create(Readable.prototype, constructor: value: ReadableHits)
ReadableHits::_read = ->
#size) {
@_current++
if @_current >= @_hits.length
if !@_next
return @push(null)
@_fetchNextPage()
else
@_shift()
return
ReadableHits::_fetchNextPage = ->
#size) {
self = this
@queryExec @from, (e, resp) ->
self._current = 0
if e
self.hits = []
self._next = false
self.emit 'error', e
return self.push(null)
self.total = resp.hits.total
self._hits = resp.hits.hits
self.from += self._hits.length
if self.from >= self.total
self._next = false
# we got them all.
if !self._hits.length
# nothing here: end the stream.
# self._next = false; // precaution but we should not really need this line.
return self.push(null)
self._shift()
return
return
ReadableHits::_shift = ->
@push @parseHit(@_hits[@_current])
return
ReadableHits::destroy = ->
if @destroyed
return
@destroyed = true
@_next = false
@unpipe()
return
# ---
# generated by js2coffee 2.2.0