All files / controllers/searchResult base.js

1.89% Statements 1/53
0% Branches 0/29
0% Functions 0/6
1.89% Lines 1/53

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 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                                                                                                                                                                                                                    1x  
let _kuzzle;
 
class SearchResultBase {
 
  /**
   *
   * @param {Kuzzle} kuzzle
   * @param {object} request
   * @param {object} options
   * @param {object} response
   */
  constructor (kuzzle, request = {}, options = {}, response = {}) {
    _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 _kuzzle.query({
        controller: this._request.controller,
        action: this._scrollAction,
        scrollId: this._response.scrollId
      }, this._options)
        .then(response => {
          const result = response.result;
          this.fetched += result.hits.length;
          this._response = result;
          this.aggregations = result.aggregations;
          this.hits = result.hits;
          return this;
        });
    }
    else if (this._request.size && this._request.sort) {
      const
        request = Object.assign({}, this._request, {
          action: this._searchAction,
          search_after: []
        }),
        hit = this._response.hits && this._response.hits[this._response.hits.length -1];
 
      for (const sort of this._request.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.search_after.push(value);
      }
 
      return _kuzzle.query(request, this._options)
        .then(response => {
          const result = response.result;
          this.fetched += result.hits.length;
          this._response = result;
          this.aggregations = result.aggregations;
          this.hits = result.hits;
          return this;
        });
    }
    else if (this._request.size) {
      if (this._request.from >= this._response.total) {
        return Promise.resolve(null);
      }
 
      return _kuzzle.query(Object.assign({}, this._request, {
        action: this._searchAction,
        from: this.fetched
      }), this._options)
        .then(response => {
          const result = response.result;
          this.fetched += result.hits.length;
          this._response = result;
          this.aggregations = result.aggregations;
          this.hits = result.hits;
          return this;
        });
    }
 
    throw new Error('Unable to retrieve next results from search: missing scrollId, from/sort, or from/size params');
  }
 
  _get (object, path) {
    if (!object) {
      return object;
    }
 
    if (path.length === 1) {
      return object[path[0]];
    }
 
    const key = path.shift();
    return this._get(object[key], path);
  }
 
}
 
 
module.exports = SearchResultBase;