ss-search
Version:
The most basic, yet powerful text search.
205 lines (148 loc) • 7.61 kB
Markdown




[](http://commitizen.github.io/cz-cli/)
[](https://github.com/semantic-release/semantic-release)
# s(imply)s(tupid)-search
### The most basic, yet powerful text search.
### Stop searching, start finding.
- **Ease of Use**: Get appropriate results instantly without any configuration.
- **Local Array Search**: Effortlessly search through a local array of objects.
- **Automatic Indexing**: No manual indexing required.
- **Precision**: Always get exactly what you're looking for.
- **Lightweight**: Depends on just 5 lodash functions for a minimized size after tree shaking.
## Demo

Still not convinced? Experience its power firsthand with this interactive [demo](https://ss-search.netlify.app/).
### Benchmark
How does it compare to other search libraries? Test out for yourself with this interactive [benchmark](https://ss-search.netlify.app/benchmark) ;)
## Install
ss-search is available on [npm](https://www.npmjs.com/package/ss-search). Install it with:
`npm install ss-search`
## Usage
### Basic
```javascript
import { search } from 'ss-search'
const data = [
{
number: 1,
text: 'A search function should be fast',
},
{
number: 2,
text: 'A search function should provide accurate results',
},
]
const searchKeys = ['text']
const searchText = 'fast search'
const results = search(data, searchKeys, searchText)
// results: [{ number: 1, text: "A search function should be fast" }]
```
It's that straightforward. No configurations, it just works.
### Data Types
Almost all data types are supported [boolean, number, string, object, array].
```javascript
// This dataset will be used as a common starting point for our type examples
const data = [
{
boolean: true,
number: 1,
string: 'search',
object: { nestedProperty: 'nested value' },
array: ['value1', 'value2'],
arrayObjects: [{ arrayObjectProperty: 'array object value' }],
},
]
```
#### Boolean
```javascript
const results = search(data, ['boolean'], 'true')
// results: will return our original dataset
```
#### Number
```javascript
const results = search(data, ['number'], '1')
// results: will return our original dataset
```
#### String
```javascript
const results = search(data, ['string'], 'search')
// results: will return our original dataset
```
#### Object
Providing a key which refers to an object will stringify that object using JSON.stringify
```javascript
const results = search(data, ['object'], 'property')
// results: will return our original dataset as it matches the property key "nestedProperty" of our object
```
If you want to access a nested property of an object to extract only a single value
```javascript
const results = search(data, ['object.nestedProperty'], 'property')
// results: will return an empty array as we extracted the value of our nested object
// if we had searched for "nested value" we would of had the original dataset
```
#### Array
Providing a key which refers to an array will stringify that array using JSON.stringify
```javascript
const results = search(data, ['array'], 'value2')
// results: will return our original dataset
```
If you have an array of objects on which you want to search all properties
```javascript
const results = search(data, ['arrayObjects'], 'arrayObjectProperty')
// results: will return an our original dataset as it's treated just like a regular array
// thus the arrayObjectProperty is part of the searchable text
```
If you have an array of objects where you want only specific properties to be searchable
```javascript
const results = search(data, ['arrayObjects[arrayObjectProperty]'], 'arrayObjectProperty')
// results: will return an empty array as we extracted the value of our nested array of objects
// if we had searched for "value object" we would of had the original dataset
```
### Options for the `search` function
Customize your search experience using the following options:
| Option parameter | Value | Description |
| ---------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `withScore` | `true` | When set to `true`, the search function will return an array of objects, each containing the matched element and its corresponding score. The score represents how closely the element matches the search text, with a higher score indicating a closer match. Even if the search doesn't match, it will return a score of 0. |
| `withScore` | `false` | When set to `false` or not provided, the function will return an array of matched elements without their scores. |
| `cacheKey` | `unknown` | The cacheKey is required if you dynamically update the `searchableKeys` as the memoization function will use the elements array by default to memoize the search tokens. |
### Example Usage
Without `withScore` option:
```javascript
const data = [{ name: 'John' }, { name: 'Jane' }, { name: 'Doe' }]
const result = search(data, ['name'], 'John')
console.log(result) // [{ name: 'John' }]
```
With `withScore` option:
```javascript
const data = [{ name: 'John' }, { name: 'Jane' }, { name: 'Doe' }]
const result = search(data, ['name'], 'John', { withScore: true })
console.log(result)
// [
// { element: { name: 'John' }, score: 1 },
// { element: { name: 'Jane' }, score: 0 },
// { element: { name: 'Doe' }, score: 0 }
// ]
```
When updating the `searchableKeys` dynamically, you need to provide a `cacheKey`:
```javascript
const data = [
{ name: 'John', age: 50 },
{ name: 'Jane', age: 40 },
]
const result1 = search(data, ['name'], 'John', { cacheKey: 'name' })
const result2 = search(data, ['age'], 40, { cacheKey: 'age' })
// result1: [{ name: 'John', age: 50 }]
// result2: [{ name: 'Jane', age: 40 }]
// If you do not manually update the cache-key, your second search would have used "name" as the `searchKeys` and returned an empty array
```

### Developing
To better manage dependencies across the monorepo I'm using [NX](https://nx.dev/).
Install dependencies:
`npm i`
Start the web-app:
`npm run web-app:serve`
Test the library:
`npm run test:all`