The module is registered on npmjs.org, to install run
npm i --save masa-search
or
yarn add masa-search
Once installed, you can pull components from the module and use them in your code.
const { Search, Type, Match } = require('masa-search');
const search = new Search();
search.addIndex({
key: 'name',
type: Type.WORD
});
search.addData([
{ name: 'Albert' },
{ name: 'Berta' },
{ name: 'Charlie' }
]);
console.log(
search.find({
condition: {
index: {
key: 'name',
type: Type.WORD
},
match: Match.EQ,
value: 'ALBERT'
}
})
);
The module was written in TypeScript and comes with its own types.
import * from 'masa-search';
const search = new Search();
...
The module is converted to a browser-library using browserify.
The dependencies are exported to the window global.
<html>
<script src="node_modules/masa-search/dist/masa-search.browser.js">
<script>
const search = new Search();
// ...
</script>
</html>
Add an index definition. All indexes should be added before adding data. Already processed data will not be re-indexed, unless manually triggered.
The index should match the following interface
interface Index {
key: string;
type: Type;
}
-
keybeing the field to be indexed. The fields may be nested, refer to _.get. -
typebeing the description of how to index the field.Typeis an enum ofenum Type { WORD = 'word', TEXT = 'text', NUMBER = 'number', DATE = 'date' }
Add new data for future searches. The data can be anything and nested as is required.
Clears the current indexed data store and re-indexes all data.
Find a set of results, based on the provided search query.
export interface Query {
and?: Query[],
or?: Query[],
condition?: Condition
}
-
andwill combine all queries with&& -
orwill combine all queries with|| -
conditionis the final condition (stops recursion)
The query should only ever have one of the keys filled and can be nested as required.
interface Condition {
index: Index,
match ?: Match,
value: any
}
-
indexbeing the index, see definition above -
matchbeing the match type whereMatchis an enum ofenum Match { EQ = '=', GT = '>', LT = '<', GTE = '>=', LTE = '<=', FUZZY = 'fuzzy', PREFIX = 'prefix', WILDCARD = 'wildcard' } -
valuebeing the value that should be compared against
The FUZZY search matches words with an auto-determined maximum distance.
- up to 4 letters: 1
- up to 8 letters: 2
- longer words: 4
The WILDCARD search mathes exact words supporting wildcards.
.a single character wildcard?the previous character is not required, but may occur+the previous character may occur repeatedly, but at least once*the previous character may occur repeatedly or not at all[]defines a selection of characters, example:[ab]matches either a or b[^]defines a negative selection of characters, example:[^ab]matches everything except a and b[-]defines a range, example:[a-d]matches every character between a and d
const { Search, Type, Match } = require('../index');
const search = new Search();
search.addIndex({
key: 'name',
type: Type.WORD
});
search.addIndex({
key: 'comment',
type: Type.TEXT
});
search.addIndex({
key: 'age',
type: Type.NUMBER
})
search.addData([
{ name: 'Albert', comment: 'He is cool', age: 25 },
{ name: 'Berta', comment: 'She is cool', age: 50 },
{ name: 'Charlie', comment: 'He is cool too', age: 35 }
]);
const query = {
and: [
{
condition: {
index: {
key: 'age',
type: Type.NUMBER
},
match: Match.GT,
value: 30
}
}, {
or: [
{
condition: {
index: {
key: 'comment',
type: Type.TEXT
},
value: 'cool too'
}
}, {
condition: {
index: {
key: 'name',
type: Type.WORD
},
value: 'Albert'
}
}
]
}
]
};
console.log(search.find(query));