All files / src/controllers/searchResult base.js

92.86% Statements 39/42
77.78% Branches 21/27
100% Functions 7/7
92.86% Lines 39/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102                    87x 87x 87x 87x   87x 87x 87x   87x 87x 87x 87x       41x 5x     36x 8x           8x   28x   8x     8x   8x   8x 18x     18x       18x     8x 8x   20x 15x 5x     10x       10x     5x       16x       16x 16x               26x 26x   26x           1x  
class SearchResultBase {
 
  /**
   *
   * @param {Kuzzle} kuzzle
   * @param {object} request
   * @param {object} options
   * @param {object} response
   */
  constructor (kuzzle, request = {}, options = {}, response = {}) {
    this._kuzzle = kuzzle;
    this._request = request;
    this._response = response;
    this._options = options;
 
    this._controller = request.controller;
    this._searchAction = 'search';
    this._scrollAction = 'scroll';
 
    this.aggregations = response.aggregations;
    this.hits = response.hits || [];
    this.fetched = this.hits.length;
    this.total = response.total || 0;
  }
 
  next () {
    if (this.fetched >= this.total) {
      return Promise.resolve(null);
    }
 
    if (this._request.scroll) {
      return this._kuzzle.query({
        controller: this._request.controller,
        action: this._scrollAction,
        scroll: this._request.scroll,
        scrollId: this._response.scrollId
      }, this._options)
        .then(response => this._buildNextSearchResult(response));
    }
    else if (this._request.size && this._request.body.sort) {
      const
        request = Object.assign({}, this._request, {
          action: this._searchAction
        }),
        hit = this._response.hits[this._response.hits.length - 1];
 
      request.body.search_after = [];
 
      for (const sort of this._request.body.sort) {
        const key = typeof sort === 'string'
          ? sort
          : Object.keys(sort)[0];
        const value = key === '_uid'
          ? this._request.collection + '#' + hit._id
          : this._get(hit._source, key.split('.'));
 
        request.body.search_after.push(value);
      }
 
      return this._kuzzle.query(request, this._options)
        .then(response => this._buildNextSearchResult(response));
    }
    else if (this._request.size) {
      if (this._request.from >= this._response.total) {
        return Promise.resolve(null);
      }
 
      return this._kuzzle.query(Object.assign({}, this._request, {
        action: this._searchAction,
        from: this.fetched
      }), this._options)
        .then(response => this._buildNextSearchResult(response));
    }
 
    throw new Error('Unable to retrieve next results from search: missing scrollId, from/sort, or from/size params');
  }
 
  _get (object, path) {
    Iif (!object) {
      return object;
    }
 
    Eif (path.length === 1) {
      return object[path[0]];
    }
 
    const key = path.shift();
    return this._get(object[key], path);
  }
 
  _buildNextSearchResult (response) {
    const nextSearchResult = new this.constructor(this._kuzzle, this._request, this._options, response.result);
    nextSearchResult.fetched += this.fetched;
 
    return nextSearchResult;
  }
 
}
 
 
module.exports = SearchResultBase;