https://github.com/vweevers/level-scout
Range search with a query plan
https://github.com/vweevers/level-scout
level nodejs proof-of-concept unmaintained-dont-use
Last synced: 10 months ago
JSON representation
Range search with a query plan
- Host: GitHub
- URL: https://github.com/vweevers/level-scout
- Owner: vweevers
- Created: 2015-05-11T15:30:24.000Z (almost 11 years ago)
- Default Branch: master
- Last Pushed: 2015-05-29T23:56:37.000Z (almost 11 years ago)
- Last Synced: 2025-04-21T13:39:26.241Z (11 months ago)
- Topics: level, nodejs, proof-of-concept, unmaintained-dont-use
- Language: JavaScript
- Homepage:
- Size: 173 KB
- Stars: 14
- Watchers: 2
- Forks: 4
- Open Issues: 5
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# level-scout
**ltgt syntax + bytewise encoded indexes + stream filters + query planner = pretty awesome search capabilities. A search will use a range query on the most optimal index, even intersect indexes if possible, or do a full scan.**
[](https://www.npmjs.org/package/level-scout) [](http://travis-ci.org/vweevers/level-scout) [](https://ci.appveyor.com/project/vweevers/level-scout) [](https://david-dm.org/vweevers/level-scout)
As an example, suppose you have a compound index on the `x` and `y` properties of your entities, resulting in index keys in the form of `[x, y, entity key]`. If you search for `x: 20, y: { gte: 5 }`, scout combines those predicates to a key range like `gte: [20, 5], lte: [20, undefined]`. But if you search for `x: { gte: 5 }, y: 20`, scout produces a ranged stream for `x` and filters that by `y`. Basically, scout can combine zero or more equality predicates with zero or one non-equality predicates, in the order of the index properties (so a compound "x, y" index is not the same as a "y, x" index). And maybe more in the future, if something like a "skip scan" is implemented.
Note: the API and dependencies are unstable, documentation is missing, terminology possibly garbled. Requires sublevel and leveldown (there are some unresolved issues with other backends like memdown). **Requires `leveldown >= 1.0.0` or `level/memdown#v1.0.2`, and JSON value encoding. Incompatible with `level-sublevel`.**
## Quick overview
```js
var index = require('level-scout/index')
search = require('level-scout/search')
select = require('level-scout/select')
filter = require('level-scout/filter')
var db = ..
index(db, 'age') // Single property index
index(db, 'owner.lastname') // Nested property
index(db, ['a', 'b', 'c']) // Compound index
// Compound index with custom mapper. You
// can now search for `sum` even though it's
// not a property of the entity. Function
// is used for both indexing and filtering.
index(db, ['a', 'sum'], function(key, entity){
return [entity.a, entity.a + entity.b]
})
// Insert some data
db.batch(..)
// Would select the "a, sum" index as access
// path, because those combined predicates are
// more selective than "age" - and "color" is not
// indexed.
var stream = search(db, {
a: 45,
sum: { gte: 45, lt: 60 },
color: 'red',
age: 300
})
// Get a subset of each entity
.pipe(select({the_age: 'age', color: true}))
// Filter some more (would yield no results)
.pipe(filter({ the_age: { lt: 100 } }))
```
Search with a callback:
```js
search(db, { year: 1988 }, function(err, results, plan){
// `plan` contains debug info about the selected
// access path and filters
})
```
## Setup
```js
var levelup = require('levelup')
, index = require('level-scout/index')
, search = require('level-scout/search')
var db = levelup('./db', { valueEncoding: 'json' })
index(db, ..)
search(db, ..)
```
Or attach the methods to your database:
```js
index.install(db)
search.install(db)
db.index('x')
db.put('key', {x: 10 }, function(){
db.search({x: 10}, function(err, results){
// ..
})
})
```