pouchdb-quick-search
Advanced tools
Comparing version 0.2.0 to 0.3.0
{ | ||
"name": "pouchdb-quick-search", | ||
"main": "dist/pouchdb.quick-search.js", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"homepage": "https://github.com/nolanlawson/pouchdb-quick-search", | ||
@@ -6,0 +6,0 @@ "authors": [ |
34
index.js
@@ -59,4 +59,9 @@ 'use strict'; | ||
// and one for the field-len-norm | ||
function createMapFunction(fieldBoosts, index) { | ||
function createMapFunction(fieldBoosts, index, filter, db) { | ||
return function (doc, emit) { | ||
if (isFiltered(doc, filter, db)) { | ||
return; | ||
} | ||
var docInfo = []; | ||
@@ -104,2 +109,3 @@ | ||
var language = opts.language || 'en'; | ||
var filter = opts.filter; | ||
@@ -134,9 +140,16 @@ if (Array.isArray(fields)) { | ||
// plus the tokenizer | ||
var persistedIndexName = 'search-' + utils.MD5(JSON.stringify({ | ||
var indexParams = { | ||
language: language, | ||
fields: fieldBoosts.map(function (x) { return x.field; }).sort() | ||
})); | ||
fields: fieldBoosts.map(function (x) { return x.field; }).sort(), | ||
}; | ||
var mapFun = createMapFunction(fieldBoosts, index); | ||
if (filter) { | ||
indexParams.filter = filter.toString(); | ||
} | ||
var persistedIndexName = 'search-' + utils.MD5(JSON.stringify(indexParams)); | ||
var mapFun = createMapFunction(fieldBoosts, index, filter, pouch); | ||
var queryOpts = { | ||
@@ -402,2 +415,13 @@ saveAs: persistedIndexName | ||
// return true if filtered, false otherwise | ||
// limit the try/catch to its own function to avoid deoptimization | ||
function isFiltered(doc, filter, db) { | ||
try { | ||
return !!(filter && !filter(doc)); | ||
} catch (e) { | ||
db.emit('error', e); | ||
return true; | ||
} | ||
} | ||
/* istanbul ignore next */ | ||
@@ -404,0 +428,0 @@ if (typeof window !== 'undefined' && window.PouchDB) { |
{ | ||
"name": "pouchdb-quick-search", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "PouchDB Quick Search - persisted full-text search for PouchDB", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -72,2 +72,3 @@ PouchDB Quick Search | ||
* [Minimum should match (mm)](#minimum-should-match-mm) | ||
* [Filtering documents](#filtering-documents) | ||
* [Building the index](#building-the-index) | ||
@@ -366,2 +367,26 @@ * [Deleting the index](#deleting-the-index) | ||
### Filtering documents | ||
If you only want to index a subset of your documents, you can include a filter function that tells us which documents to skip. The filter function should return `true` for documents you want to index, and `false` for documents you want to skip. (Truthy/falsy values are also okay.) | ||
Example: | ||
```js | ||
pouch.search({ | ||
query: 'foo', | ||
fields: ['title', 'text'], | ||
filter: function (doc) { | ||
return doc.type === 'person'; // only index persons | ||
} | ||
}).then(function (info) { | ||
// handle result | ||
}).catch(function (err) { | ||
// handle error | ||
}); | ||
``` | ||
The `filter` option, like `fields` and `language`, affects the identity of the underlying index, so it affects building and deleting (see building/deleting below). | ||
Thanks to [Jean-Felix Girard](https://github.com/jfgirard) for implementing this feature! | ||
### Building the index | ||
@@ -379,3 +404,3 @@ | ||
// if build was successful, info is {"ok": true} | ||
}).then(function (err) { | ||
}).catch(function (err) { | ||
// handle error | ||
@@ -387,3 +412,3 @@ }); | ||
You must at least provide the `fields` you want to index. Boosts don't matter. | ||
You must at least provide the `fields` you want to index. If the language isn't English, you must pass in the `language` option. Boosts don't matter. | ||
@@ -401,3 +426,3 @@ ### Deleting the index | ||
When you do this, you _must_ at least provide the `fields`, because external databases are created and identified based on the fields you want to index. I.e. for every unique `fields` combination you want to index, a separate database will be created especially for that query. If you open up your developer tools, you can see it; it should have a name like `<mydbname>-search-<md5sum>` and look like this: | ||
When you do this, you _must_ at least provide the `fields`, because external databases are created and identified based on the fields you want to index. You should also provide the `language` option if the language is something other than English. I.e., for every unique `fields` combination you want to index (plus `language` if non-English), a separate database will be created especially for that query. If you open up your developer tools, you can see it; it should have a name like `<mydbname>-search-<md5sum>` and look like this: | ||
@@ -404,0 +429,0 @@ ![extra database created for search](https://raw.githubusercontent.com/nolanlawson/pouchdb-quick-search/master/docs/extra_database.png) |
@@ -676,3 +676,50 @@ /*jshint expr:true */ | ||
}); | ||
it('search with filter', function () { | ||
// the word "court" is used in all 3 docs | ||
// but we filter out the doc._id === "2" | ||
return db.bulkDocs({docs: docs}).then(function () { | ||
var opts = { | ||
fields: ['title', 'text', 'desc'], | ||
query: 'court', | ||
filter: function (doc) { return doc._id !== "2"; } | ||
}; | ||
return db.search(opts); | ||
}).then(function (res) { | ||
res.rows.length.should.equal(2); | ||
var ids = res.rows.map(function (x) { return x.id; }); | ||
ids.should.deep.equal(['3', '1']); | ||
}); | ||
}); | ||
it('search with filter - Error thrown ', function () { | ||
//the filter function will throw an Error for | ||
//one doc, which filter it out. | ||
var error; | ||
//filter function throw an error ? | ||
db.on('error', function (err) { | ||
error = err; | ||
}); | ||
return db.bulkDocs({docs: docs}).then(function () { | ||
var opts = { | ||
fields: ['title', 'text', 'desc'], | ||
query: 'court', | ||
filter: function (doc) { if (doc._id === '1') { throw new Error("oups"); } return true; } | ||
}; | ||
return db.search(opts); | ||
}).then(function (res) { | ||
res.rows.length.should.equal(2); | ||
var ids = res.rows.map(function (x) { return x.id; }); | ||
ids.should.deep.equal(['2', '3']); | ||
error.should.have.property('message', 'oups'); | ||
}); | ||
}); | ||
}); | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
575
1286266
30047