All files / src/index StringIndex.js

97.3% Statements 36/37
100% Branches 14/14
100% Functions 13/13
97.06% Lines 33/34
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    9x 9x 9x   9x           21x 21x         140x 140x   126x   98x       140x         14x               14x   140x 140x                     180x         14x     5x   9x             5x 5x   50x 50x   20x     5x         12x 9x   90x 90x     18x     9x       9x 9x    
"use strict";
 
const Index = require('./Index');
const extractObjectValues = require('../misc/extractObjectValues');
const decoder = require('unidecode');
 
const INDEX_TYPE = 'string';
 
class StringIndex extends Index
{
  constructor(config = {}, type = undefined)
  {
    super(config, type || INDEX_TYPE);
    this.filters = ['match', 'exists'];
  }
 
  getDocumentValues(document)
  {
    const values = [];
    extractObjectValues(document, this.fields, (value, field, scale) =>
    {
      if (typeof value === 'string')
      {
        values.push(decoder(value)
          .toLowerCase());
      }
    });
    return values;
  }
 
  createIndex()
  {
    return [];
  }
 
  async addToIndex(index, documentIndices, documentsValues)
  {
    /**
     * O(documentIndices)
     */
    documentIndices.forEach((documentIndex, valuesOffset) =>
    {
      let value = documentsValues[valuesOffset];
      index[documentIndex] = Object.keys(value)
        .join('|');
    });
    // console.log(documentsValues, index)
  }
 
  /**
   * O(documentIndices)
   */
  async removeFromIndex(index, documentIndices, documentsValues)
  {
    documentIndices.forEach(documentIndex => index[documentIndex] = null);
  }
 
  filterBasedOnIndex(index, filter, results)
  {
    switch (filter.filter)
    {
    case 'exists':
      return this.filterExistsImpl(index, filter, results);
    case 'match':
      return this.filterMatchImpl(index, filter, results);
    }
    return results;
  }
 
  filterExistsImpl(index, filter, results)
  {
    const targetValue = filter.values[0].toLowerCase() === 'true';
    for (let resultIndex = 0; resultIndex < index.length; resultIndex++)
    {
      const exists = !!(index[resultIndex]);
      if (targetValue === exists)
      {
        results.addHit(resultIndex, 1);
      }
    }
    return results;
  }
 
  filterMatchImpl(index, filter, results)
  {
    filter.values = filter.values.map(value => value.toLowerCase())
    for (let resultIndex = 0; resultIndex < index.length; resultIndex++)
    {
      const values = index[resultIndex];
      if (values && filter.values.filter(value => values.indexOf(value) === -1)
        .length === 0)
      {
        results.addHit(resultIndex, 1);
      }
    }
    return results;
  }
}
 
module.exports = StringIndex;
require('./register')
  .add(StringIndex, INDEX_TYPE);