UNPKG

mfsearch

Version:

Indexed search for MasterFormat-style datasets

77 lines (69 loc) 2.42 kB
const _ = require('lodash'); const { Search, SimpleTokenizer, StemmingTokenizer, UnorderedSearchIndex, } = require('js-search'); const { stemmer } = require('porter-stemmer'); class MFSearch { // // by default, exclude all of divisions 40-46, 34, and 35 constructor({ mfData, subsetRE = /^(?!(34|35|4[0123456]))/ }) { this.searchData = _.map(_.filter(mfData, (item) => { return item.code.match(subsetRE); }), (item, idx) => { return { code: item.code, level: item.level, description: item.description, primaryText: `${item.code} ${item.description}`, key: idx, }; }); const { stemmer } = require('porter-stemmer'); this.search = new Search('description'); this.search.tokenizer = new StemmingTokenizer(stemmer, new SimpleTokenizer()); this.search.searchIndex = new UnorderedSearchIndex(); this.search.addIndex('description'); this.search.addIndex('code'); this.search.addDocuments(this.searchData); } // // Full scan of search dataset locate ({ filterText = undefined, codePrefix = undefined, level = undefined }) { let ret; if (_.isUndefined(filterText)) { ret = this.searchData; } else { ret = this.search.search(filterText); } if (!_.isUndefined(level)) { ret = _.filter(ret, (item) => { return item.level == level; }); } if (!_.isUndefined(codePrefix)) { ret = _.filter(ret, (item) => { return _.startsWith(item.code, codePrefix); }); } return ret; }; // // Return division (Level 1) items, optionally filtered. divisions ({ filterText = undefined }) { return this.locate({ filterText, level: 1 }); } // // Return group (Level 2) items within specified division, optionally filtered. groupsOfDivision ({ filterText = undefined, divisionCode = '' }) { return this.locate({ filterText, codePrefix: divisionCode.substring(0,2), level: 2}); } // // Return Level 3 items within specified division, optionally filtered. lineItemsOfGroup ({ filterText = undefined, groupCode = '' }) { return this.locate({ filterText, codePrefix: groupCode.substring(0,3), level: 3 }); } } const codeStem = ({ code, level=1 }) => { const stemLength = level+1; if (level<1 || level>3 || code.length < stemLength ) return code; return code.substring(0,stemLength); }; module.exports = { MFSearch, codeStem };