scour-search

Fast searching

Usage no npm install needed!

<script type="module">
  import scourSearch from 'https://cdn.skypack.dev/scour-search';
</script>

README

scour-search

Indexed searching

import Searcher from 'scour-search'

data =
  { 1: { name: 'Homer', gender: 'm' },
    2: { name: 'Marge', gender: 'f' },
    3: { name: 'Bart', gender: 'm' } }

search = Searcher(data)
  .index('name')

search.filter({ gender: 'm' })
// => { 1: { name: 'Homer', gender: 'm' },
//      3: { name: 'Bart', gender: 'm' } }

Status

MongoDB-style queries

Supported operations (fast): $or, $and, $not, $nor, $in, $nin, $eq, $ne.

Supported operations (slow): $lt, $gt, $gte, $lte, $exists, $regex, $where, $size, $mod.

search.filter({ $or: [ {name: 'Homer'}, {gender: 'f'} ] })

Updating data

Use reindex() to tell scour-search that there's updated data. It works immutably.

data = { ... }

search = ss(data).index('name')

newData = { ...data, 4: { name: 'John' } }

search = search.reindex(newData, 4)
// `4` is the key of the new entry

Arrays and objects

scour-search works for both Arrays and array-like Objects. Performance is much faster with Objects (see benchmarks).

// array
data = [
  { symbol: 'AAPL', name: 'Apple' },
  { symbol: 'MSFT', name: 'Microsoft' },
  { symbol: 'FB', name: 'Facebook' }
]

// object
data = {
  aapl: { symbol: 'AAPL', name: 'Apple' },
  msft: { symbol: 'MSFT', name: 'Microsoft' },
  fb: { symbol: 'FB', name: 'Facebook' }
}

Benchmarks

searching (n=512)
    x 44221 op/sec - indexed, array
    x 405108 op/sec - indexed, object
    x 21761 op/sec - unindexed, array
    x 6104 op/sec - via sift.js
    x 37525 op/sec - native Array.filter()

API

Searcher

Searcher(data)

Creates a searcher object where you can search given data.

import Searcher from 'scour-search'

data = [ { symbol: 'AAPL' }, { symbol: 'MSFT' } ]

search = Searcher(data)
search.filter({ symbol: 'AAPL' })

// Add indexing via .index()
search = search.index('symbol')
search.filter({ symbol: 'AAPL' })

index

index(field, type)

Creates an index for the field field. This allows searches against this field to be faster.

This function is mutative; it will modify the current Searcher instance.

data = [
  { name: 'John' }, { name: 'Paul' }
]

search = Searcher(data)
search.filter({ name: 'John' }) // ...slow (no index)

search = Searcher(data).index('name')
search.filter({ name: 'John' }) // ...fast

reindex

reindex(newData, keys)

Given new newData, update the indices for keys. The parameter keys can be an array, a number, or a string.

The parameter newData must be different from data, but based off of it. (scour-search is biased towards immutable workflows.)

data = [ { name: 'john' } ]
search = Searcher(data).index('name')

// An addition at key `1`
newData = [ { name: 'john' }, { name: 'ringo' } ]
search = search.reindex(newData, 1)

// An deletion at key `1`
newData = [ { name: 'john' } ]
search = search.reindex(newData, 1)

filter

filter(condition)

Performs a query. Supports some MongoDB-style filters.

search = Searcher(data)

search.filter({ name: 'John' })
search.filter({ name: { $eq: 'John' } })
search.filter({ name: { $in: ['John', 'George'] } })

indexOf

indexOf(condition)

Returns the index. If it's not found, returns -1. For arrays, it will return a numeric index. For objects, it will return the key string of the match.

search = Searcher([ { id: 'AAPL' }, { id: 'GOOG' } ])
search.indexOf({ id: 'GOOG' })      // => 1

search = Searcher({ aapl: { name: 'Apple' } })
search.indexOf({ name: 'Apple' })   // => 'aapl'

filterKeys

filterKeys(condition)

Performs a query, and only returns keys.

Thanks

scour-search © 2015+, Rico Sta. Cruz. Released under the MIT License.
Authored and maintained by Rico Sta. Cruz with help from contributors (list).

ricostacruz.com  ·  GitHub @rstacruz  ·  Twitter @rstacruz