From 5281b127476108c083f54bdc762588ec2ee5ea6d Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sat, 19 Nov 2022 21:16:09 +0100 Subject: [PATCH 01/21] Maintain mapping from ID to short ID This speeds up removal, allows checking for duplicate IDs upon adding a document, and prepares the ground to implement discarding documents by ID. --- src/MiniSearch.test.js | 11 ++++++- src/MiniSearch.ts | 70 +++++++++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index fded67e8..6257c7fc 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -40,6 +40,15 @@ describe('MiniSearch', () => { }).toThrowError('MiniSearch: document does not have ID field "foo"') }) + it('throws error on duplicate ID', () => { + const ms = new MiniSearch({ idField: 'foo', fields: ['title', 'text'] }) + ms.add({ foo: 'abc', text: 'Something' }) + + expect(() => { + ms.add({ foo: 'abc', text: 'I have a duplicate ID' }) + }).toThrowError('MiniSearch: duplicate ID abc') + }) + it('extracts the ID field using extractField', () => { const extractField = (document, fieldName) => { if (fieldName === 'id') { return document.id.value } @@ -534,7 +543,7 @@ describe('MiniSearch', () => { it('computes a meaningful score when fields are named liked default properties of object', () => { const ms = new MiniSearch({ fields: ['constructor'] }) ms.add({ id: 1, constructor: 'something' }) - ms.add({ id: 1, constructor: 'something else' }) + ms.add({ id: 2, constructor: 'something else' }) const results = ms.search('something') results.forEach((result) => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 63a76b4d..56133d9d 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -395,6 +395,7 @@ export default class MiniSearch { protected _index: SearchableMap protected _documentCount: number protected _documentIds: Map + protected _idToShortId: Map protected _fieldIds: { [key: string]: number } protected _fieldLength: Map protected _avgFieldLength: number[] @@ -480,6 +481,8 @@ export default class MiniSearch { this._documentIds = new Map() + this._idToShortId = new Map() + // Fields are defined during initialization, don't change, are few in // number, rarely need iterating over, and have string keys. Therefore in // this case an object is a better candidate than a Map to store the mapping @@ -509,6 +512,10 @@ export default class MiniSearch { throw new Error(`MiniSearch: document does not have ID field "${idField}"`) } + if (this._idToShortId.has(id)) { + throw new Error(`MiniSearch: duplicate ID ${id}`) + } + const shortDocumentId = this.addDocumentId(id) this.saveStoredFields(shortDocumentId, document) @@ -597,39 +604,39 @@ export default class MiniSearch { throw new Error(`MiniSearch: document does not have ID field "${idField}"`) } - for (const [shortId, longId] of this._documentIds) { - if (id === longId) { - for (const field of fields) { - const fieldValue = extractField(document, field) - if (fieldValue == null) continue - - const tokens = tokenize(fieldValue.toString(), field) - const fieldId = this._fieldIds[field] - - const uniqueTerms = new Set(tokens).size - this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms) - - for (const term of tokens) { - const processedTerm = processTerm(term, field) - if (Array.isArray(processedTerm)) { - for (const t of processedTerm) { - this.removeTerm(fieldId, shortId, t) - } - } else if (processedTerm) { - this.removeTerm(fieldId, shortId, processedTerm) - } + const shortId = this._idToShortId.get(id) + + if (shortId == null) { + throw new Error(`MiniSearch: cannot remove document with ID ${id}: it is not in the index`) + } + + for (const field of fields) { + const fieldValue = extractField(document, field) + if (fieldValue == null) continue + + const tokens = tokenize(fieldValue.toString(), field) + const fieldId = this._fieldIds[field] + + const uniqueTerms = new Set(tokens).size + this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms) + + for (const term of tokens) { + const processedTerm = processTerm(term, field) + if (Array.isArray(processedTerm)) { + for (const t of processedTerm) { + this.removeTerm(fieldId, shortId, t) } + } else if (processedTerm) { + this.removeTerm(fieldId, shortId, processedTerm) } - - this._storedFields.delete(shortId) - this._documentIds.delete(shortId) - this._fieldLength.delete(shortId) - this._documentCount -= 1 - return } } - throw new Error(`MiniSearch: cannot remove document with ID ${id}: it is not in the index`) + this._storedFields.delete(shortId) + this._documentIds.delete(shortId) + this._idToShortId.delete(id) + this._fieldLength.delete(shortId) + this._documentCount -= 1 } /** @@ -650,6 +657,7 @@ export default class MiniSearch { this._index = new SearchableMap() this._documentCount = 0 this._documentIds = new Map() + this._idToShortId = new Map() this._fieldLength = new Map() this._avgFieldLength = [] this._storedFields = new Map() @@ -996,12 +1004,17 @@ export default class MiniSearch { miniSearch._documentCount = documentCount miniSearch._nextId = nextId miniSearch._documentIds = objectToNumericMap(documentIds) + miniSearch._idToShortId = new Map() miniSearch._fieldIds = fieldIds miniSearch._fieldLength = objectToNumericMap(fieldLength) miniSearch._avgFieldLength = averageFieldLength miniSearch._storedFields = objectToNumericMap(storedFields) miniSearch._index = new SearchableMap() + for (const [shortId, id] of miniSearch._documentIds) { + miniSearch._idToShortId.set(id, shortId) + } + for (const [term, data] of index) { const dataMap = new Map() as FieldTermData @@ -1296,6 +1309,7 @@ export default class MiniSearch { */ private addDocumentId (documentId: any): number { const shortDocumentId = this._nextId + this._idToShortId.set(documentId, shortDocumentId) this._documentIds.set(shortDocumentId, documentId) this._documentCount += 1 this._nextId += 1 From 312ba3fbd6298cd7f64427f24e130f41b9533024 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sat, 19 Nov 2022 23:00:13 +0100 Subject: [PATCH 02/21] Add discard method as an alternative to remove The MiniSearch.discard method has the same visible effect of MiniSearch.remove (both cause the document to stop appearing in search results), but a different effect on the inverted index: MiniSearch.remove takes as argument the full document, and removes it from the inverted index, releasing memory immediately. MiniSearch.discard instead only needs the document ID, and marks the current version of the document as discarded so it is ignored in search results. The inverted index is not modified though, so memory is not released. Upon search, whenever a discarded ID is found, it is ignored, and the inverted index for the search terms is cleaned up removing the discarded documents. This partially releases memory, but only for terms that have been searched at least once after discarding the document. --- src/MiniSearch.test.js | 82 ++++++++++++++++++++++++++++++++++++++++++ src/MiniSearch.ts | 66 +++++++++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 1 deletion(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 6257c7fc..0fdf37a7 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -433,6 +433,88 @@ describe('MiniSearch', () => { }) }) + describe('discard', () => { + it('prevents a document from appearing in search results', () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some interesting stuff' }, + { id: 2, text: 'Some more interesting stuff' } + ] + ms.addAll(documents) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([1, 2]) + + ms.discard(1) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([2]) + }) + + it('adjusts metadata as if the document was removed', () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some interesting stuff' }, + { id: 2, text: 'Some more interesting stuff' } + ] + ms.addAll(documents) + const clone = MiniSearch.loadJSON(JSON.stringify(ms), { + fields: ['text'] + }) + + ms.discard(1) + clone.remove({ id: 1, text: 'Some interesting stuff' }) + + expect(ms._idToShortId).toEqual(clone._idToShortId) + expect(ms._documentIds).toEqual(clone._documentIds) + expect(ms._fieldLength).toEqual(clone._fieldLength) + expect(ms._avgFieldLength).toEqual(clone._avgFieldLength) + expect(ms._documentCount).toEqual(clone._documentCount) + }) + + it('allows adding a new version of the document afterwards', () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some interesting stuff' }, + { id: 2, text: 'Some more interesting stuff' } + ] + ms.addAll(documents) + + ms.discard(1) + ms.add({ id: 1, text: 'Some new stuff' }) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([1, 2]) + expect(ms.search('new').map((doc) => doc.id)).toEqual([1]) + + ms.discard(1) + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([2]) + + ms.add({ id: 1, text: 'Some newer stuff' }) + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([1, 2]) + expect(ms.search('new').map((doc) => doc.id)).toEqual([]) + expect(ms.search('newer').map((doc) => doc.id)).toEqual([1]) + }) + + it('leaves the index in the same state as removal when all terms are searched at least once', () => { + const ms = new MiniSearch({ fields: ['text'] }) + const document = { id: 1, text: 'Some stuff' } + ms.add(document) + const clone = MiniSearch.loadJSON(JSON.stringify(ms), { + fields: ['text'] + }) + + ms.discard(1) + clone.remove({ id: 1, text: 'Some stuff' }) + + expect(ms).not.toEqual(clone) + + const results = ms.search('some stuff') + + expect(ms).toEqual(clone) + + // Results are the same after the first search + expect(ms.search('stuff')).toEqual(results) + }) + }) + describe('addAll', () => { it('adds all the documents to the index', () => { const ms = new MiniSearch({ fields: ['text'] }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 56133d9d..df74b6ac 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -594,6 +594,12 @@ export default class MiniSearch { * 2. apply changes * 3. index new version * + * This method is the cleanest way to remove a document, as it removes it from + * the inverted index. On the other hand, it requires having the full document + * to remove at hand. An alternative approach is [[MiniSearch.discard]], which + * only needs the ID of the document and has the same visible effect as + * remove, but does not immediately free up memory from the inverted index. + * * @param document The document to be removed */ remove (document: T): void { @@ -665,6 +671,54 @@ export default class MiniSearch { } } + /** + * Discards the document with the given ID, so it won't appear in search results + * + * It has the same visible effect of [[MiniSearch.remove]] (both cause the + * document to stop appearing in search results), but a different effect on + * the internal data structures: + * + * [[MiniSearch.remove]] takes the full document as argument, and removes it + * from the inverted index, releasing memory immediately. + * + * [[MiniSearch.discard]] instead only needs the document ID, and marks the + * current version of the document as discarded so it is ignored in search + * results. The inverted index is not modified though, so memory is not + * released. Upon search, whenever a discarded ID is found, it is filtered out + * from the results, and the inverted index for the search terms is cleaned up + * removing the discarded documents. This partially releases memory, but only + * for terms that have been searched at least once after discarding the + * document. + * + * In other words, [[MiniSearch.discard]] is faster and only takes an ID as + * argument, but it does not release memory for the discarded document. + * + * After discarding a document, it is possible to re-add a document with that + * same ID, and the newly added version will appear in searches. In other + * words, discarding and re-adding a document has the same effect, as visible + * to the caller of MiniSearch, as removing and re-adding it. + * + * @param id The ID of the document to be discarded + */ + discard (id: any): void { + const shortId = this._idToShortId.get(id) + + if (shortId == null) { + throw new Error(`MiniSearch: cannot discard document with ID ${id}: it is not in the index`) + } + + this._idToShortId.delete(id) + this._documentIds.delete(shortId) + + ;(this._fieldLength.get(shortId) || []).forEach((fieldLength, fieldId) => { + this.removeFieldLength(shortId, fieldId, this._documentCount, fieldLength) + }) + + this._fieldLength.delete(shortId) + + this._documentCount -= 1 + } + /** * Search for documents matching the given search query. * @@ -1204,10 +1258,16 @@ export default class MiniSearch { const fieldTermFreqs = fieldTermData.get(fieldId) if (fieldTermFreqs == null) continue - const matchingFields = fieldTermFreqs.size + let matchingFields = fieldTermFreqs.size const avgFieldLength = this._avgFieldLength[fieldId] for (const docId of fieldTermFreqs.keys()) { + if (!this._documentIds.has(docId)) { + this.removeTerm(fieldId, docId, derivedTerm) + matchingFields -= 1 + continue + } + const docBoost = boostDocumentFn ? boostDocumentFn(this._documentIds.get(docId), derivedTerm) : 1 if (!docBoost) continue @@ -1342,6 +1402,10 @@ export default class MiniSearch { * @ignore */ private removeFieldLength (documentId: number, fieldId: number, count: number, length: number): void { + if (count === 1) { + this._avgFieldLength[fieldId] = 0 + return + } const totalFieldLength = (this._avgFieldLength[fieldId] * count) - length this._avgFieldLength[fieldId] = totalFieldLength / (count - 1) } From 048e32e00201bae83cc5e214f1f5367a787969b8 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sat, 19 Nov 2022 23:50:05 +0100 Subject: [PATCH 03/21] Implement MiniSearch.has method To test if a document with the given ID was added to the index. --- src/MiniSearch.test.js | 40 ++++++++++++++++++++++++++++++++++++++++ src/MiniSearch.ts | 9 +++++++++ 2 files changed, 49 insertions(+) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 0fdf37a7..c98272a2 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -575,6 +575,46 @@ describe('MiniSearch', () => { }) }) + describe('has', () => { + it('returns true if a document with the given ID was added to the index, false otherwise', () => { + const documents = [ + { id: 1, title: 'Divina Commedia', text: 'Nel mezzo del cammin di nostra vita' }, + { id: 2, title: 'I Promessi Sposi', text: 'Quel ramo del lago di Como' }, + ] + const ms = new MiniSearch({ fields: ['title', 'text'] }) + ms.addAll(documents) + + expect(ms.has(1)).toEqual(true) + expect(ms.has(2)).toEqual(true) + expect(ms.has(3)).toEqual(false) + + ms.remove({ id: 1, title: 'Divina Commedia', text: 'Nel mezzo del cammin di nostra vita' }) + ms.discard(2) + + expect(ms.has(1)).toEqual(false) + expect(ms.has(2)).toEqual(false) + }) + + it('works well with custom ID fields', () => { + const documents = [ + { uid: 1, title: 'Divina Commedia', text: 'Nel mezzo del cammin di nostra vita' }, + { uid: 2, title: 'I Promessi Sposi', text: 'Quel ramo del lago di Como' }, + ] + const ms = new MiniSearch({ fields: ['title', 'text'], idField: 'uid' }) + ms.addAll(documents) + + expect(ms.has(1)).toEqual(true) + expect(ms.has(2)).toEqual(true) + expect(ms.has(3)).toEqual(false) + + ms.remove({ uid: 1, title: 'Divina Commedia', text: 'Nel mezzo del cammin di nostra vita' }) + ms.discard(2) + + expect(ms.has(1)).toEqual(false) + expect(ms.has(2)).toEqual(false) + }) + }) + describe('search', () => { const documents = [ { id: 1, title: 'Divina Commedia', text: 'Nel mezzo del cammin di nostra vita' }, diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index df74b6ac..74006d5d 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -719,6 +719,15 @@ export default class MiniSearch { this._documentCount -= 1 } + /** + * Returns true if a document with the given ID was added to the index, false otherwise + * + * @param id The document ID + */ + has (id: any) { + return this._idToShortId.has(id) + } + /** * Search for documents matching the given search query. * From b06147196f538462f0a0cea18287ec613a7d03b8 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 01:37:41 +0100 Subject: [PATCH 04/21] Add cleanupDiscarded method to clean up index This method traverses the inverted index in batches and cleans up discarded documents. --- src/MiniSearch.test.js | 25 ++++++++++++++++++ src/MiniSearch.ts | 59 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index c98272a2..a60be635 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -515,6 +515,31 @@ describe('MiniSearch', () => { }) }) + describe('cleanupDiscarded', () => { + it('cleans up discarded documents from the index', async () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + const clone = MiniSearch.loadJSON(JSON.stringify(ms), { + fields: ['text'] + }) + + ms.discard(1) + ms.discard(2) + clone.remove({ id: 1, text: 'Some stuff' }) + clone.remove({ id: 2, text: 'Some additional stuff' }) + + expect(ms).not.toEqual(clone) + + await ms.cleanupDiscarded({ batchSize: 1 }) + + expect(ms).toEqual(clone) + }) + }) + describe('addAll', () => { it('adds all the documents to the index', () => { const ms = new MiniSearch({ fields: ['text'] }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 74006d5d..2bc61b58 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -698,6 +698,10 @@ export default class MiniSearch { * words, discarding and re-adding a document has the same effect, as visible * to the caller of MiniSearch, as removing and re-adding it. * + * The [[MiniSearch.cleanupDiscarded]] method can be called to traverse and + * clean up the index and release memory, usually after [[MiniSearch.discard]] + * is used to discard several documents. + * * @param id The ID of the document to be discarded */ discard (id: any): void { @@ -719,6 +723,61 @@ export default class MiniSearch { this._documentCount -= 1 } + /** + * Cleans up discarded documents from the inverted index + * + * This function is only useful for applications that make use of + * [[MiniSearch.discard]]. + * + * Traverses all terms in the inverted index in batches, and cleans up + * discarded documents from the posting list, releasing memory. It takes an + * option argument with keys: + * + * - `batchSize`: the size of each batch (1000 by default) + * - `batchWait`: the number of milliseconds to wait between batches, to + * avoid blocking the thread (10 by default) + * + * Applications that make use of [[MiniSearch.discard]] on long-lived indexes + * can call this function to clean up the index and release memory. + * + * It returns a void promise, that resolves when the whole inverted index was + * traversed, and the clean up completed. + * + * On large indexes, this method can be expensive and take time to complete, + * hence the batching and wait to avoid blocking the thread for too long. + * Therefore, it is usually better to call this method only occasionally, + * after several calls to [[MiniSearch.discard]] have been made. + * + * @param options Configuration options for the batch size and delay + */ + async cleanupDiscarded (options: { batchSize?: number, batchWait?: number } = {}): Promise { + const { batchSize, batchWait } = { batchSize: 1000, batchWait: 10, ...options } + let i = 0 + + for (const [term, fieldsData] of this._index) { + for (const [fieldId, fieldIndex] of fieldsData) { + for (const [shortId] of fieldIndex) { + if (this._documentIds.has(shortId)) { continue } + + if (fieldIndex.size <= 1) { + fieldsData.delete(fieldId) + } else { + fieldIndex.delete(shortId) + } + } + } + + if (this._index.get(term)!.size === 0) { + this._index.delete(term) + } + + i += 1 + if (i % batchSize === 0) { + await new Promise((resolve) => setTimeout(resolve, batchWait)) + } + } + } + /** * Returns true if a document with the given ID was added to the index, false otherwise * From 66457e01c09428c997963c46c7f31b1c1d3a43be Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 13:20:57 +0100 Subject: [PATCH 05/21] CLean up stored fields upon discard --- src/MiniSearch.test.js | 13 ++++++++----- src/MiniSearch.ts | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index a60be635..919daac2 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -466,12 +466,13 @@ describe('MiniSearch', () => { expect(ms._idToShortId).toEqual(clone._idToShortId) expect(ms._documentIds).toEqual(clone._documentIds) expect(ms._fieldLength).toEqual(clone._fieldLength) + expect(ms._storedFields).toEqual(clone._storedFields) expect(ms._avgFieldLength).toEqual(clone._avgFieldLength) expect(ms._documentCount).toEqual(clone._documentCount) }) it('allows adding a new version of the document afterwards', () => { - const ms = new MiniSearch({ fields: ['text'] }) + const ms = new MiniSearch({ fields: ['text'], storeFields: ['text'] }) const documents = [ { id: 1, text: 'Some interesting stuff' }, { id: 2, text: 'Some more interesting stuff' } @@ -494,11 +495,12 @@ describe('MiniSearch', () => { }) it('leaves the index in the same state as removal when all terms are searched at least once', () => { - const ms = new MiniSearch({ fields: ['text'] }) + const ms = new MiniSearch({ fields: ['text'], storeFields: ['text'] }) const document = { id: 1, text: 'Some stuff' } ms.add(document) const clone = MiniSearch.loadJSON(JSON.stringify(ms), { - fields: ['text'] + fields: ['text'], + storeFields: ['text'] }) ms.discard(1) @@ -517,14 +519,15 @@ describe('MiniSearch', () => { describe('cleanupDiscarded', () => { it('cleans up discarded documents from the index', async () => { - const ms = new MiniSearch({ fields: ['text'] }) + const ms = new MiniSearch({ fields: ['text'], storeFields: ['text'] }) const documents = [ { id: 1, text: 'Some stuff' }, { id: 2, text: 'Some additional stuff' } ] ms.addAll(documents) const clone = MiniSearch.loadJSON(JSON.stringify(ms), { - fields: ['text'] + fields: ['text'], + storeFields: ['text'] }) ms.discard(1) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 2bc61b58..cc37284e 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -713,6 +713,7 @@ export default class MiniSearch { this._idToShortId.delete(id) this._documentIds.delete(shortId) + this._storedFields.delete(shortId) ;(this._fieldLength.get(shortId) || []).forEach((fieldLength, fieldId) => { this.removeFieldLength(shortId, fieldId, this._documentCount, fieldLength) From aeb8aa5b9ee1f3ffecdd84c2ffba5e6f1d4c81f0 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 16:24:26 +0100 Subject: [PATCH 06/21] Auto vacuuming of discarded documents --- src/MiniSearch.test.js | 64 +++++++++++++++-- src/MiniSearch.ts | 159 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 206 insertions(+), 17 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 919daac2..ae857e25 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -449,7 +449,7 @@ describe('MiniSearch', () => { expect(ms.search('stuff').map((doc) => doc.id)).toEqual([2]) }) - it('adjusts metadata as if the document was removed', () => { + it('adjusts internal data to account for the document being discarded', () => { const ms = new MiniSearch({ fields: ['text'] }) const documents = [ { id: 1, text: 'Some interesting stuff' }, @@ -469,6 +469,7 @@ describe('MiniSearch', () => { expect(ms._storedFields).toEqual(clone._storedFields) expect(ms._avgFieldLength).toEqual(clone._avgFieldLength) expect(ms._documentCount).toEqual(clone._documentCount) + expect(ms._dirtCount).toEqual(1) }) it('allows adding a new version of the document afterwards', () => { @@ -510,14 +511,44 @@ describe('MiniSearch', () => { const results = ms.search('some stuff') - expect(ms).toEqual(clone) + expect(ms._index).toEqual(clone._index) // Results are the same after the first search expect(ms.search('stuff')).toEqual(results) }) + + it('triggers auto vacuum when the threshold is met', () => { + const ms = new MiniSearch({ fields: ['text'], autoVacuum: { minDirtCount: 2, minDirtFactor: 0, batchWait: 50, batchSize: 1 } }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + + expect(ms.isVacuuming).toEqual(false) + + ms.discard(1) + expect(ms.isVacuuming).toEqual(false) + + ms.discard(2) + expect(ms.isVacuuming).toEqual(true) + }) + + it('does not trigger auto vacuum if disabled', () => { + const ms = new MiniSearch({ fields: ['text'], autoVacuum: false }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + ms._dirtCount = 1000 + + ms.discard(1) + expect(ms.isVacuuming).toEqual(false) + }) }) - describe('cleanupDiscarded', () => { + describe('vacuum', () => { it('cleans up discarded documents from the index', async () => { const ms = new MiniSearch({ fields: ['text'], storeFields: ['text'] }) const documents = [ @@ -537,9 +568,34 @@ describe('MiniSearch', () => { expect(ms).not.toEqual(clone) - await ms.cleanupDiscarded({ batchSize: 1 }) + await ms.vacuum({ batchSize: 1 }) expect(ms).toEqual(clone) + expect(ms.isVacuuming).toEqual(false) + }) + + it('schedules a second vacuum right after the current one completes, if one is ongoing', async () => { + const ms = new MiniSearch({ fields: ['text'] }) + const empty = MiniSearch.loadJSON(JSON.stringify(ms), { + fields: ['text'] + }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + + ms.discard(1) + ms.discard(2) + ms.add({ id: 3, text: 'Even more stuff' }) + + ms.vacuum({ batchSize: 1, batchWait: 50 }) + ms.discard(3) + + await ms.vacuum() + + expect(ms._index).toEqual(empty._index) + expect(ms.isVacuuming).toEqual(false) }) }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index cc37284e..f5a19915 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -189,6 +189,15 @@ export type Options = { */ logger?: (level: LogLevel, message: string, code?: string) => void + /** + * If true (the default), vacuuming is performed automatically as soon as + * [[MiniSearch.discard]] is called a certain number of times, to clean up + * discarded documents from the index. If false, no auto-vacuuming is + * performed. Custom auto vacuuming settings can be passed as an object (see + * the [[AutoVacuumOptions]] type). + */ + autoVacuum?: boolean | AutoVacuumOptions + /** * Default search options (see the [[SearchOptions]] type and the * [[MiniSearch.search]] method for details) @@ -203,19 +212,21 @@ export type Options = { } type OptionsWithDefaults = Options & { - storeFields: string[], + storeFields: string[] - idField: string, + idField: string - extractField: (document: T, fieldName: string) => string, + extractField: (document: T, fieldName: string) => string - tokenize: (text: string, fieldName: string) => string[], + tokenize: (text: string, fieldName: string) => string[] - processTerm: (term: string, fieldName: string) => string | string[] | null | undefined | false, + processTerm: (term: string, fieldName: string) => string | string[] | null | undefined | false logger: (level: LogLevel, message: string, code?: string) => void - searchOptions: SearchOptionsWithDefaults, + autoVacuum: false | AutoVacuumOptions + + searchOptions: SearchOptionsWithDefaults autoSuggestOptions: SearchOptions } @@ -294,6 +305,7 @@ export type AsPlainObject = { fieldLength: { [shortId: string]: number[] } averageFieldLength: number[], storedFields: { [shortId: string]: any } + dirtCount?: number, index: [string, { [fieldId: string]: SerializedIndexEntry }][] serializationVersion: number } @@ -306,6 +318,47 @@ export type QueryCombination = SearchOptions & { queries: Query[] } */ export type Query = QueryCombination | string +/** + * Options to control auto vacuum behavior. When discarding a document with + * [[MiniSearch.discard]], if vacuuming is not already in progress, and the + * dirtCount and dirtFactor are above the thresholds defined by this + * configuration, a vacuuming cycle is automatically started. + */ +export type AutoVacuumOptions = VacuumOptions & { + /** + * Minimum dirt factor under which auto vacuum is not triggered. It defaults + * to 0.15. + */ + minDirtFactor?: number, + + /** + * Minimum dirt count (number of discarded documents since the last vacuuming) + * under which auto vacuum is not triggered. It defaults to 100. + */ + minDirtCount?: number +} + +/** + * Options to control vacuuming behavior. Vacuuming is only necessary when + * discarding documents with [[MiniSearch.discard]], and is a potentially costly + * operation on large indexes because it has to traverse the whole inverted + * index. Therefore, in order to avoid blocking the thread for long, it is + * performed in batches, with a delay between each batch. These options are used + * to configure the batch size and the delay between batches. + */ +export type VacuumOptions = { + /** + * Size of each vacuuming batch (the number of termsin the inverted index that + * will be traversed in each batch). Defaults to 1000. + */ + batchSize?: number, + + /** + * Wait time between each vacuuming batch in milliseconds. Defaults to 10. + */ + batchWait?: number +} + type QuerySpec = { prefix: boolean, fuzzy: number | boolean, @@ -401,6 +454,9 @@ export default class MiniSearch { protected _avgFieldLength: number[] protected _nextId: number protected _storedFields: Map> + protected _dirtCount: number + private _currentVacuum: Promise | null + private _vacuumEnqueued: boolean /** * @param options Configuration options @@ -471,6 +527,7 @@ export default class MiniSearch { this._options = { ...defaultOptions, ...options, + autoVacuum: !!options.autoVacuum && (options.autoVacuum === true ? defaultAutoVacuumOptions : options.autoVacuum), searchOptions: { ...defaultSearchOptions, ...(options.searchOptions || {}) }, autoSuggestOptions: { ...defaultAutoSuggestOptions, ...(options.autoSuggestOptions || {}) } } @@ -497,6 +554,12 @@ export default class MiniSearch { this._storedFields = new Map() + this._dirtCount = 0 + + this._currentVacuum = null + + this._vacuumEnqueued = false + this.addFields(this._options.fields) } @@ -698,9 +761,12 @@ export default class MiniSearch { * words, discarding and re-adding a document has the same effect, as visible * to the caller of MiniSearch, as removing and re-adding it. * - * The [[MiniSearch.cleanupDiscarded]] method can be called to traverse and - * clean up the index and release memory, usually after [[MiniSearch.discard]] - * is used to discard several documents. + * By default, vacuuming is performed automatically when a sufficient number + * of documents are discarded, traversing the inverted index and releasing + * memory by cleaning up discarded documents (see [[Options.autoVacuum]] and + * [[AutoVacuumOptions]]). + * + * Alternatively, the [[MiniSearch.vacuum]] method can be called manually. * * @param id The ID of the document to be discarded */ @@ -722,6 +788,15 @@ export default class MiniSearch { this._fieldLength.delete(shortId) this._documentCount -= 1 + this._dirtCount += 1 + + if (this._options.autoVacuum === false) { return } + + const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum + if (this.dirtCount >= (minDirtCount || defaultAutoVacuumOptions.minDirtCount) && + this.dirtFactor >= (minDirtFactor || defaultAutoVacuumOptions.minDirtFactor)) { + this.vacuum({ batchSize, batchWait }) + } } /** @@ -741,8 +816,13 @@ export default class MiniSearch { * Applications that make use of [[MiniSearch.discard]] on long-lived indexes * can call this function to clean up the index and release memory. * - * It returns a void promise, that resolves when the whole inverted index was - * traversed, and the clean up completed. + * It returns a promise that resolves (to undefined) when the whole inverted + * index was traversed, and the clean up completed. If a vacuuming cycle is + * already ongoing at the time this method is called, a new one is enqueued + * immediately after the ongoing one completes, and the corresponding promise + * is returned. No more than one vacuuming is enqueued on top of the ongoing + * one though, even if this method is called more times (as enqueuing multiple + * ones would be useless). * * On large indexes, this method can be expensive and take time to complete, * hence the batching and wait to avoid blocking the thread for too long. @@ -751,8 +831,25 @@ export default class MiniSearch { * * @param options Configuration options for the batch size and delay */ - async cleanupDiscarded (options: { batchSize?: number, batchWait?: number } = {}): Promise { - const { batchSize, batchWait } = { batchSize: 1000, batchWait: 10, ...options } + vacuum (options: VacuumOptions = {}): Promise { + // If a vacuum is already ongoing, schedule another as soon as it finishes, + // unless there's already one queuing + if (this._currentVacuum) { + if (this._vacuumEnqueued) { return this._currentVacuum } + + this._vacuumEnqueued = true + return this._currentVacuum.then(() => this.performVacuuming(options)) + } + + this._currentVacuum = this.performVacuuming(options) + + return this._currentVacuum + } + + private async performVacuuming (options: VacuumOptions = {}): Promise { + const initialDirtCount = this._dirtCount + + const { batchSize, batchWait } = { ...defaultVacuumOptions, ...options } let i = 0 for (const [term, fieldsData] of this._index) { @@ -777,6 +874,35 @@ export default class MiniSearch { await new Promise((resolve) => setTimeout(resolve, batchWait)) } } + + this._vacuumEnqueued = false + this._currentVacuum = null + this._dirtCount -= initialDirtCount + } + + /** + * Is true if a vacuuming operation is ongoing, false otherwise + */ + get isVacuuming (): boolean { + return this._currentVacuum != null + } + + /** + * The number of documents discarded since the last vacuuming + */ + get dirtCount (): number { + return this._dirtCount + } + + /** + * A number between 0 and 1 giving an indication about the proportion of + * documents that are discarded, and can therefore be cleaned up by vacuuming. + * A value close to 0 means that the index is relatively clean, while a higher + * value means that the index is relatively dirty, and vacuuming could release + * memory. + */ + get dirtFactor (): number { + return this._dirtCount / (1 + this._documentCount + this._dirtCount) } /** @@ -1116,6 +1242,7 @@ export default class MiniSearch { fieldLength, averageFieldLength, storedFields, + dirtCount, serializationVersion } = js if (serializationVersion !== 1 && serializationVersion !== 2) { @@ -1132,6 +1259,7 @@ export default class MiniSearch { miniSearch._fieldLength = objectToNumericMap(fieldLength) miniSearch._avgFieldLength = averageFieldLength miniSearch._storedFields = objectToNumericMap(storedFields) + miniSearch._dirtCount = dirtCount || 0 miniSearch._index = new SearchableMap() for (const [shortId, id] of miniSearch._documentIds) { @@ -1301,6 +1429,7 @@ export default class MiniSearch { fieldLength: Object.fromEntries(this._fieldLength), averageFieldLength: this._avgFieldLength, storedFields: Object.fromEntries(this._storedFields), + dirtCount: this._dirtCount, index, serializationVersion: 2 } @@ -1593,6 +1722,10 @@ const defaultAutoSuggestOptions = { i === terms.length - 1 } +const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } + +const defaultAutoVacuumOptions = { minDirtFactor: 0.15, minDirtCount: 100, ...defaultVacuumOptions } + const assignUniqueTerm = (target: string[], term: string): void => { // Avoid adding duplicate terms. if (!target.includes(term)) target.push(term) From 41f00fa91fb8989e4a57c26b9576bea4bf5d37be Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 16:59:25 +0100 Subject: [PATCH 07/21] Add missing test --- src/MiniSearch.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index ae857e25..5379a5d2 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -449,6 +449,14 @@ describe('MiniSearch', () => { expect(ms.search('stuff').map((doc) => doc.id)).toEqual([2]) }) + it('raises error if a document with the given ID does not exist', () => { + const ms = new MiniSearch({ fields: ['text'] }) + + expect(() => { + ms.discard(99) + }).toThrow('MiniSearch: cannot discard document with ID 99: it is not in the index') + }) + it('adjusts internal data to account for the document being discarded', () => { const ms = new MiniSearch({ fields: ['text'] }) const documents = [ From 4ec9c6908b17763733c8c7f579cb1e311d746dd4 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 19:49:12 +0100 Subject: [PATCH 08/21] Fix promise returned by vacuum when another vacuuming is in progress --- src/MiniSearch.test.js | 19 +++++++++++++++++++ src/MiniSearch.ts | 14 +++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 5379a5d2..4dd292e0 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -605,6 +605,25 @@ describe('MiniSearch', () => { expect(ms._index).toEqual(empty._index) expect(ms.isVacuuming).toEqual(false) }) + + it('does not enqueue more than one vacuum on top of the ongoing one', async () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + + ms.addAll(documents) + ms.discard(1) + ms.discard(2) + + const a = ms.vacuum({ batchSize: 1, batchWait: 50 }) + const b = ms.vacuum() + const c = ms.vacuum() + + expect(a).not.toBe(b) + expect(b).toBe(c) + }) }) describe('addAll', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index f5a19915..64504834 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -456,7 +456,7 @@ export default class MiniSearch { protected _storedFields: Map> protected _dirtCount: number private _currentVacuum: Promise | null - private _vacuumEnqueued: boolean + private _enqueuedVacuum: Promise | null /** * @param options Configuration options @@ -558,7 +558,7 @@ export default class MiniSearch { this._currentVacuum = null - this._vacuumEnqueued = false + this._enqueuedVacuum = null this.addFields(this._options.fields) } @@ -835,10 +835,10 @@ export default class MiniSearch { // If a vacuum is already ongoing, schedule another as soon as it finishes, // unless there's already one queuing if (this._currentVacuum) { - if (this._vacuumEnqueued) { return this._currentVacuum } + if (this._enqueuedVacuum != null) { return this._enqueuedVacuum } - this._vacuumEnqueued = true - return this._currentVacuum.then(() => this.performVacuuming(options)) + this._enqueuedVacuum = this._currentVacuum.then(() => this.performVacuuming(options)) + return this._enqueuedVacuum } this._currentVacuum = this.performVacuuming(options) @@ -875,8 +875,8 @@ export default class MiniSearch { } } - this._vacuumEnqueued = false - this._currentVacuum = null + this._currentVacuum = this._enqueuedVacuum + this._enqueuedVacuum = null this._dirtCount -= initialDirtCount } From 81b1431aee9d78e4423c200136aea865be7ac061 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 20:09:53 +0100 Subject: [PATCH 09/21] Improve documentation --- src/MiniSearch.test.js | 5 +++ src/MiniSearch.ts | 80 +++++++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 4dd292e0..3a907159 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -623,6 +623,11 @@ describe('MiniSearch', () => { expect(a).not.toBe(b) expect(b).toBe(c) + expect(ms.isVacuuming).toEqual(true) + + await c + + expect(ms.isVacuuming).toEqual(false) }) }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 64504834..9e161d93 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -744,28 +744,34 @@ export default class MiniSearch { * [[MiniSearch.remove]] takes the full document as argument, and removes it * from the inverted index, releasing memory immediately. * - * [[MiniSearch.discard]] instead only needs the document ID, and marks the - * current version of the document as discarded so it is ignored in search - * results. The inverted index is not modified though, so memory is not - * released. Upon search, whenever a discarded ID is found, it is filtered out - * from the results, and the inverted index for the search terms is cleaned up - * removing the discarded documents. This partially releases memory, but only - * for terms that have been searched at least once after discarding the - * document. + * [[MiniSearch.discard]] instead only needs the document ID, and works by + * marking the current version of the document as discarded, scausing it to be + * ignored by search. The inverted index is not modified though, therefore + * memory is not released. + * + * The memory bloat resulting from repetite calls to [[MiniSearch.discard]] is + * cleaned up later by two mechanisms: clean up during search, and vacuuming. + * Upom search, whenever a discarded ID is found (and ignored for the + * results), references to the discarded document are removed from the + * inverted index entries for the search terms. This partially releases + * memory, but only for terms that have been searched at least once after + * discarding the document. + * + * Vacuuming is performed automatically (by default) after a certain number of + * documents are discarded, and traverses the inverted index cleaning up all + * references to discarded documents (see [[Options.autoVacuum]] and + * [[AutoVacuumOptions]]). Alternatively, manual vacuuming can be performed + * with [[MiniSearch.vacuum]]. * * In other words, [[MiniSearch.discard]] is faster and only takes an ID as - * argument, but it does not release memory for the discarded document. + * argument, but it does not immediately release memory for the discarded + * document, and instead rely on delayed clean up and vacuuming. * - * After discarding a document, it is possible to re-add a document with that - * same ID, and the newly added version will appear in searches. In other + * After discarding a document, it is possible to re-add a new version with + * that same ID, and the newly added version will appear in searches. In other * words, discarding and re-adding a document has the same effect, as visible * to the caller of MiniSearch, as removing and re-adding it. * - * By default, vacuuming is performed automatically when a sufficient number - * of documents are discarded, traversing the inverted index and releasing - * memory by cleaning up discarded documents (see [[Options.autoVacuum]] and - * [[AutoVacuumOptions]]). - * * Alternatively, the [[MiniSearch.vacuum]] method can be called manually. * * @param id The ID of the document to be discarded @@ -800,40 +806,40 @@ export default class MiniSearch { } /** - * Cleans up discarded documents from the inverted index + * Triggers a manual vacuuming, that cleans up discarded documents from the + * inverted index * - * This function is only useful for applications that make use of - * [[MiniSearch.discard]]. + * This function is only useful for applications that use the + * [[MiniSearch.discard]] method. Vacuuming traverses all terms in the + * inverted index in batches, and cleans up discarded documents from the + * posting list, releasing memory. While vacuuming is performed automatically + * by default (see [[AutoVacuumOptions]]), one can call this method to perfrom + * it manually. * - * Traverses all terms in the inverted index in batches, and cleans up - * discarded documents from the posting list, releasing memory. It takes an - * option argument with keys: + * The method takes an option argument with the following keys: * * - `batchSize`: the size of each batch (1000 by default) + * * - `batchWait`: the number of milliseconds to wait between batches, to * avoid blocking the thread (10 by default) * - * Applications that make use of [[MiniSearch.discard]] on long-lived indexes - * can call this function to clean up the index and release memory. - * - * It returns a promise that resolves (to undefined) when the whole inverted - * index was traversed, and the clean up completed. If a vacuuming cycle is - * already ongoing at the time this method is called, a new one is enqueued - * immediately after the ongoing one completes, and the corresponding promise - * is returned. No more than one vacuuming is enqueued on top of the ongoing - * one though, even if this method is called more times (as enqueuing multiple - * ones would be useless). + * It returns a promise that resolves (to undefined) when the clean up is + * completed. If vacuuming is already ongoing at the time this method is + * called, a new one is enqueued immediately after the ongoing one, and a + * corresponding promise is returned. No more than one vacuuming is enqueued + * on top of the ongoing one though, even if this method is called more times + * (enqueuing multiple ones would be useless). * - * On large indexes, this method can be expensive and take time to complete, - * hence the batching and wait to avoid blocking the thread for too long. - * Therefore, it is usually better to call this method only occasionally, - * after several calls to [[MiniSearch.discard]] have been made. + * On large indexes, vacuuming can be expensive and take time to complete, + * hence the batching and wait to avoid blocking the thread for long. + * Therefore, this method should only be called when necessary, usually after + * several calls to [[MiniSearch.discard]], or before serializing the index. * * @param options Configuration options for the batch size and delay */ vacuum (options: VacuumOptions = {}): Promise { // If a vacuum is already ongoing, schedule another as soon as it finishes, - // unless there's already one queuing + // unless there's already one queued if (this._currentVacuum) { if (this._enqueuedVacuum != null) { return this._enqueuedVacuum } From 73606159ae730e3d41d2ee205488baf689536dd7 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 20:19:53 +0100 Subject: [PATCH 10/21] Change auto vacuum defaults and improve behavior --- src/MiniSearch.test.js | 7 ++++++- src/MiniSearch.ts | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 3a907159..5744d993 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -529,7 +529,8 @@ describe('MiniSearch', () => { const ms = new MiniSearch({ fields: ['text'], autoVacuum: { minDirtCount: 2, minDirtFactor: 0, batchWait: 50, batchSize: 1 } }) const documents = [ { id: 1, text: 'Some stuff' }, - { id: 2, text: 'Some additional stuff' } + { id: 2, text: 'Some additional stuff' }, + { id: 3, text: 'Even more stuff' } ] ms.addAll(documents) @@ -540,6 +541,10 @@ describe('MiniSearch', () => { ms.discard(2) expect(ms.isVacuuming).toEqual(true) + + // It does not enqueue another vacuuming if one is ongoing + ms.discard(3) + expect(ms._enqueuedVacuum).toEqual(null) }) it('does not trigger auto vacuum if disabled', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 9e161d93..451eb336 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -333,7 +333,7 @@ export type AutoVacuumOptions = VacuumOptions & { /** * Minimum dirt count (number of discarded documents since the last vacuuming) - * under which auto vacuum is not triggered. It defaults to 100. + * under which auto vacuum is not triggered. It defaults to 20. */ minDirtCount?: number } @@ -796,7 +796,7 @@ export default class MiniSearch { this._documentCount -= 1 this._dirtCount += 1 - if (this._options.autoVacuum === false) { return } + if (this._options.autoVacuum === false || this.isVacuuming) { return } const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum if (this.dirtCount >= (minDirtCount || defaultAutoVacuumOptions.minDirtCount) && @@ -1730,7 +1730,7 @@ const defaultAutoSuggestOptions = { const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } -const defaultAutoVacuumOptions = { minDirtFactor: 0.15, minDirtCount: 100, ...defaultVacuumOptions } +const defaultAutoVacuumOptions = { minDirtFactor: 0.15, minDirtCount: 20, ...defaultVacuumOptions } const assignUniqueTerm = (target: string[], term: string): void => { // Avoid adding duplicate terms. From 1dbd7a766352d36f72ca48b46b11a68b2bf62707 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 20:24:40 +0100 Subject: [PATCH 11/21] Remove unnecessary default --- src/MiniSearch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 451eb336..8f6a6c1c 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -852,7 +852,7 @@ export default class MiniSearch { return this._currentVacuum } - private async performVacuuming (options: VacuumOptions = {}): Promise { + private async performVacuuming (options: VacuumOptions): Promise { const initialDirtCount = this._dirtCount const { batchSize, batchWait } = { ...defaultVacuumOptions, ...options } From 96ee3df05223dbab4e233c8315bfe4d144698bbf Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Sun, 20 Nov 2022 20:34:24 +0100 Subject: [PATCH 12/21] Fix and test a corner case with autovacuuming options --- src/MiniSearch.test.js | 35 ++++++++++++++++++++++++++++++++++- src/MiniSearch.ts | 3 ++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 5744d993..d8d8ef37 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -526,7 +526,10 @@ describe('MiniSearch', () => { }) it('triggers auto vacuum when the threshold is met', () => { - const ms = new MiniSearch({ fields: ['text'], autoVacuum: { minDirtCount: 2, minDirtFactor: 0, batchWait: 50, batchSize: 1 } }) + const ms = new MiniSearch({ + fields: ['text'], + autoVacuum: { minDirtCount: 2, minDirtFactor: 0, batchWait: 50, batchSize: 1 } + }) const documents = [ { id: 1, text: 'Some stuff' }, { id: 2, text: 'Some additional stuff' }, @@ -559,6 +562,36 @@ describe('MiniSearch', () => { ms.discard(1) expect(ms.isVacuuming).toEqual(false) }) + + it('applies default settings if autoVacuum is set to true', () => { + const ms = new MiniSearch({ fields: ['text'], autoVacuum: true }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + ms._dirtCount = 1000 + + ms.discard(1) + expect(ms.isVacuuming).toEqual(true) + }) + + it('applies default settings if options are set to null', async () => { + const ms = new MiniSearch({ + fields: ['text'], + autoVacuum: { minDirtCount: null, minDirtFactor: null, batchWait: null, batchSize: null } + }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + ms._dirtCount = 1000 + + const x = ms.discard(1) + expect(ms.isVacuuming).toEqual(true) + await x + }) }) describe('vacuum', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 8f6a6c1c..6f5e4769 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -855,7 +855,8 @@ export default class MiniSearch { private async performVacuuming (options: VacuumOptions): Promise { const initialDirtCount = this._dirtCount - const { batchSize, batchWait } = { ...defaultVacuumOptions, ...options } + const batchSize = options.batchSize || defaultVacuumOptions.batchSize + const batchWait = options.batchWait || defaultVacuumOptions.batchWait let i = 0 for (const [term, fieldsData] of this._index) { From b10d8efe56cfc014aa993428a258c218acbfc8ae Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Mon, 21 Nov 2022 11:26:47 +0100 Subject: [PATCH 13/21] Implement replace method --- src/MiniSearch.test.js | 29 +++++++++++++++++++++++++++++ src/MiniSearch.ts | 24 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index d8d8ef37..ca2cc791 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -594,6 +594,35 @@ describe('MiniSearch', () => { }) }) + describe('replace', () => { + it('replaces an existing document with a new version', () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some quite interesting stuff' }, + { id: 2, text: 'Some more interesting stuff' } + ] + ms.addAll(documents) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([1, 2]) + expect(ms.search('quite').map((doc) => doc.id)).toEqual([1]) + expect(ms.search('even').map((doc) => doc.id)).toEqual([]) + + ms.replace({ id: 1, text: 'Some even more interesting stuff' }) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([2, 1]) + expect(ms.search('quite').map((doc) => doc.id)).toEqual([]) + expect(ms.search('even').map((doc) => doc.id)).toEqual([1]) + }) + + it('raises error if a document with the given ID does not exist', () => { + const ms = new MiniSearch({ fields: ['text'] }) + + expect(() => { + ms.replace({ id: 1, text: 'Some stuff' }) + }).toThrow('MiniSearch: cannot discard document with ID 1: it is not in the index') + }) + }) + describe('vacuum', () => { it('cleans up discarded documents from the index', async () => { const ms = new MiniSearch({ fields: ['text'], storeFields: ['text'] }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 6f5e4769..6ec2c0ba 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -805,6 +805,30 @@ export default class MiniSearch { } } + /** + * It replaces an existing document with the given updated version + * + * It works by discarding the current version and adding the updated one, so + * it is functionally equivalent to calling [[MiniSearch.discard]] followed by + * [[MiniSearch.add]]. The ID of the updated document should match the + * one to be replaced. + * + * Since it relies on [[MiniSearch.discard]], this method does not immediately + * release memory for the replaced document, and instead relies on vacuuming + * to clean up eventually (see [[MiniSearch.discard]] and + * [[Options.autoVacuum]]). + * + * @param updatedDocument The updated document to replace the old version + * with + */ + replace (updatedDocument: T): void { + const { idField, extractField } = this._options + const id = extractField(updatedDocument, idField) + + this.discard(id) + this.add(updatedDocument) + } + /** * Triggers a manual vacuuming, that cleans up discarded documents from the * inverted index From a72f6527d5e0ca192ad666ab45c0ab8c7f6aeb1b Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Mon, 21 Nov 2022 14:39:20 +0100 Subject: [PATCH 14/21] Fix autovacuum behavior on multiple calls to discard --- src/MiniSearch.test.js | 49 ++++++++++++++-- src/MiniSearch.ts | 124 +++++++++++++++++++++++------------------ 2 files changed, 116 insertions(+), 57 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index ca2cc791..89645c9c 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -544,10 +544,6 @@ describe('MiniSearch', () => { ms.discard(2) expect(ms.isVacuuming).toEqual(true) - - // It does not enqueue another vacuuming if one is ongoing - ms.discard(3) - expect(ms._enqueuedVacuum).toEqual(null) }) it('does not trigger auto vacuum if disabled', () => { @@ -592,6 +588,51 @@ describe('MiniSearch', () => { expect(ms.isVacuuming).toEqual(true) await x }) + + it('vacuums until under the dirt thresholds when called multiple times', async () => { + const minDirtCount = 2 + const ms = new MiniSearch({ + fields: ['text'], + autoVacuum: { minDirtCount, minDirtFactor: 0, batchSize: 1, batchWait: 10 } + }) + const documents = [] + for (let i = 0; i < 5; i++) { + documents.push({ id: i + 1, text: `Document number ${i}` }) + } + ms.addAll(documents) + + expect(ms._dirtCount).toEqual(0) + + documents.forEach((doc) => ms.discard(doc.id)) + + while (ms.isVacuuming) { + await ms._currentVacuum + } + + expect(ms._dirtCount).toBeLessThan(minDirtCount) + }) + + it('does not perform unnecessary vacuuming when called multiple times', async () => { + const minDirtCount = 2 + const ms = new MiniSearch({ + fields: ['text'], + autoVacuum: { minDirtCount, minDirtFactor: 0, batchSize: 1, batchWait: 10 } + }) + const documents = [ + { id: 1, text: 'Document one' }, + { id: 2, text: 'Document two' }, + { id: 3, text: 'Document three' }, + ] + ms.addAll(documents) + + documents.forEach((doc) => ms.discard(doc.id)) + + while (ms.isVacuuming) { + await ms._currentVacuum + } + + expect(ms._dirtCount).toBe(1) + }) }) describe('replace', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 6ec2c0ba..291fb7d9 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -318,26 +318,6 @@ export type QueryCombination = SearchOptions & { queries: Query[] } */ export type Query = QueryCombination | string -/** - * Options to control auto vacuum behavior. When discarding a document with - * [[MiniSearch.discard]], if vacuuming is not already in progress, and the - * dirtCount and dirtFactor are above the thresholds defined by this - * configuration, a vacuuming cycle is automatically started. - */ -export type AutoVacuumOptions = VacuumOptions & { - /** - * Minimum dirt factor under which auto vacuum is not triggered. It defaults - * to 0.15. - */ - minDirtFactor?: number, - - /** - * Minimum dirt count (number of discarded documents since the last vacuuming) - * under which auto vacuum is not triggered. It defaults to 20. - */ - minDirtCount?: number -} - /** * Options to control vacuuming behavior. Vacuuming is only necessary when * discarding documents with [[MiniSearch.discard]], and is a potentially costly @@ -359,12 +339,34 @@ export type VacuumOptions = { batchWait?: number } +export type VacuumConditions = { + /** + * Minimum dirt factor under which auto vacuum is not triggered. It defaults + * to 0.15. + */ + minDirtFactor?: number, + + /** + * Minimum dirt count (number of discarded documents since the last vacuuming) + * under which auto vacuum is not triggered. It defaults to 20. + */ + minDirtCount?: number +} + type QuerySpec = { prefix: boolean, fuzzy: number | boolean, term: string } +/** + * Options to control auto vacuum behavior. When discarding a document with + * [[MiniSearch.discard]], if vacuuming is not already in progress, and the + * dirtCount and dirtFactor are above the thresholds defined by this + * configuration, a vacuuming cycle is automatically started. + */ +export type AutoVacuumOptions = VacuumOptions & VacuumConditions + type DocumentTermFreqs = Map type FieldTermData = Map @@ -796,13 +798,10 @@ export default class MiniSearch { this._documentCount -= 1 this._dirtCount += 1 - if (this._options.autoVacuum === false || this.isVacuuming) { return } + if (this._options.autoVacuum === false) { return } const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum - if (this.dirtCount >= (minDirtCount || defaultAutoVacuumOptions.minDirtCount) && - this.dirtFactor >= (minDirtFactor || defaultAutoVacuumOptions.minDirtFactor)) { - this.vacuum({ batchSize, batchWait }) - } + this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor }) } /** @@ -850,65 +849,84 @@ export default class MiniSearch { * It returns a promise that resolves (to undefined) when the clean up is * completed. If vacuuming is already ongoing at the time this method is * called, a new one is enqueued immediately after the ongoing one, and a - * corresponding promise is returned. No more than one vacuuming is enqueued - * on top of the ongoing one though, even if this method is called more times - * (enqueuing multiple ones would be useless). + * corresponding promise is returned. However, no more than one vacuuming is + * enqueued on top of the ongoing one, even if this method is called more + * times (enqueuing multiple ones would be useless). * * On large indexes, vacuuming can be expensive and take time to complete, * hence the batching and wait to avoid blocking the thread for long. * Therefore, this method should only be called when necessary, usually after * several calls to [[MiniSearch.discard]], or before serializing the index. * - * @param options Configuration options for the batch size and delay + * @param options Configuration options for the batch size and delay. See + * [[VacuumOptions]]. */ vacuum (options: VacuumOptions = {}): Promise { + return this.conditionalVacuum(options) + } + + private conditionalVacuum (options: VacuumOptions, conditions?: VacuumConditions): Promise { // If a vacuum is already ongoing, schedule another as soon as it finishes, // unless there's already one queued if (this._currentVacuum) { if (this._enqueuedVacuum != null) { return this._enqueuedVacuum } - this._enqueuedVacuum = this._currentVacuum.then(() => this.performVacuuming(options)) + this._enqueuedVacuum = this._currentVacuum.then(() => this.performVacuuming(options, conditions)) return this._enqueuedVacuum } - this._currentVacuum = this.performVacuuming(options) + if (this.vacuumConditionsMet(conditions) === false) { return Promise.resolve() } + this._currentVacuum = this.performVacuuming(options) return this._currentVacuum } - private async performVacuuming (options: VacuumOptions): Promise { + private async performVacuuming (options: VacuumOptions, conditions?: VacuumConditions): Promise { const initialDirtCount = this._dirtCount - const batchSize = options.batchSize || defaultVacuumOptions.batchSize - const batchWait = options.batchWait || defaultVacuumOptions.batchWait - let i = 0 - - for (const [term, fieldsData] of this._index) { - for (const [fieldId, fieldIndex] of fieldsData) { - for (const [shortId] of fieldIndex) { - if (this._documentIds.has(shortId)) { continue } - - if (fieldIndex.size <= 1) { - fieldsData.delete(fieldId) - } else { - fieldIndex.delete(shortId) + if (this.vacuumConditionsMet(conditions)) { + const batchSize = options.batchSize || defaultVacuumOptions.batchSize + const batchWait = options.batchWait || defaultVacuumOptions.batchWait + let i = 0 + + for (const [term, fieldsData] of this._index) { + for (const [fieldId, fieldIndex] of fieldsData) { + for (const [shortId] of fieldIndex) { + if (this._documentIds.has(shortId)) { continue } + + if (fieldIndex.size <= 1) { + fieldsData.delete(fieldId) + } else { + fieldIndex.delete(shortId) + } } } - } - if (this._index.get(term)!.size === 0) { - this._index.delete(term) - } + if (this._index.get(term)!.size === 0) { + this._index.delete(term) + } - i += 1 - if (i % batchSize === 0) { - await new Promise((resolve) => setTimeout(resolve, batchWait)) + i += 1 + if (i % batchSize === 0) { + await new Promise((resolve) => setTimeout(resolve, batchWait)) + } } + + this._dirtCount -= initialDirtCount } this._currentVacuum = this._enqueuedVacuum this._enqueuedVacuum = null - this._dirtCount -= initialDirtCount + } + + private vacuumConditionsMet (conditions?: VacuumConditions) { + if (conditions == null) { return true } + + let { minDirtCount, minDirtFactor } = conditions + minDirtCount = minDirtCount || defaultAutoVacuumOptions.minDirtCount + minDirtFactor = minDirtFactor || defaultAutoVacuumOptions.minDirtFactor + + return this.dirtCount >= minDirtCount && this.dirtFactor >= minDirtFactor } /** From cb710b58b6491fd5217650c9ff0b5af3d14914fe Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Tue, 22 Nov 2022 12:06:33 +0100 Subject: [PATCH 15/21] Always apply broadest conditions to enqueued vacuum --- src/MiniSearch.test.js | 38 ++++++++++++++++++++++++++++++++++++++ src/MiniSearch.ts | 16 +++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 89645c9c..353678de 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -603,6 +603,9 @@ describe('MiniSearch', () => { expect(ms._dirtCount).toEqual(0) + // Calling discard multiple times should start an auto-vacuum and enqueue + // another, so that the remaining dirt count afterwards is always below + // minDirtCount documents.forEach((doc) => ms.discard(doc.id)) while (ms.isVacuuming) { @@ -625,6 +628,10 @@ describe('MiniSearch', () => { ] ms.addAll(documents) + // Calling discard multiple times will start an auto-vacuum and enqueue + // another, subject to minDirtCount/minDirtFactor conditions. The last one + // should be a no-op, as the remaining dirt count after the first auto + // vacuum would be 1, which is below minDirtCount documents.forEach((doc) => ms.discard(doc.id)) while (ms.isVacuuming) { @@ -633,6 +640,37 @@ describe('MiniSearch', () => { expect(ms._dirtCount).toBe(1) }) + + it('enqueued vacuum runs without conditions if a manual vacuum was called while enqueued', async () => { + const minDirtCount = 2 + const ms = new MiniSearch({ + fields: ['text'], + autoVacuum: { minDirtCount, minDirtFactor: 0, batchSize: 1, batchWait: 10 } + }) + const documents = [ + { id: 1, text: 'Document one' }, + { id: 2, text: 'Document two' }, + { id: 3, text: 'Document three' }, + ] + ms.addAll(documents) + + // Calling discard multiple times will start an auto-vacuum and enqueue + // another, subject to minDirtCount/minDirtFactor conditions. The last one + // would be a no-op, as the remaining dirt count after the first auto + // vacuum would be 1, which is below minDirtCount + documents.forEach((doc) => ms.discard(doc.id)) + + // But before the enqueued vacuum is ran, we invoke a manual vacuum with + // no conditions, so it should run even with a dirt count below + // minDirtCount + ms.vacuum() + + while (ms.isVacuuming) { + await ms._currentVacuum + } + + expect(ms._dirtCount).toBe(0) + }) }) describe('replace', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 291fb7d9..b5d0be6a 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -459,6 +459,7 @@ export default class MiniSearch { protected _dirtCount: number private _currentVacuum: Promise | null private _enqueuedVacuum: Promise | null + private _enqueuedVacuumConditions: VacuumConditions | undefined /** * @param options Configuration options @@ -561,6 +562,7 @@ export default class MiniSearch { this._currentVacuum = null this._enqueuedVacuum = null + this._enqueuedVacuumConditions = defaultVacuumConditions this.addFields(this._options.fields) } @@ -867,11 +869,18 @@ export default class MiniSearch { private conditionalVacuum (options: VacuumOptions, conditions?: VacuumConditions): Promise { // If a vacuum is already ongoing, schedule another as soon as it finishes, - // unless there's already one queued + // unless there's already one enqueued. If one was already enqueued, do not + // enqueue another on top, but make sure that the conditions are the + // broadest. if (this._currentVacuum) { + this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && conditions if (this._enqueuedVacuum != null) { return this._enqueuedVacuum } - this._enqueuedVacuum = this._currentVacuum.then(() => this.performVacuuming(options, conditions)) + this._enqueuedVacuum = this._currentVacuum.then(() => { + const conditions = this._enqueuedVacuumConditions + this._enqueuedVacuumConditions = defaultVacuumConditions + return this.performVacuuming(options, conditions) + }) return this._enqueuedVacuum } @@ -1772,8 +1781,9 @@ const defaultAutoSuggestOptions = { } const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } +const defaultVacuumConditions = { minDirtFactor: 0.15, minDirtCount: 20 } -const defaultAutoVacuumOptions = { minDirtFactor: 0.15, minDirtCount: 20, ...defaultVacuumOptions } +const defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions } const assignUniqueTerm = (target: string[], term: string): void => { // Avoid adding duplicate terms. From 1182167e94356923ab04cabdb4a21644952f3d10 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Tue, 22 Nov 2022 13:48:21 +0100 Subject: [PATCH 16/21] Fix issue when batch is bigger than number of documents --- src/MiniSearch.test.js | 11 +++++++++++ src/MiniSearch.ts | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index 353678de..a0333ee3 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -775,6 +775,17 @@ describe('MiniSearch', () => { expect(ms.isVacuuming).toEqual(false) }) + + it('allows batch size to be bigger than the term count', async () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some stuff' }, + { id: 2, text: 'Some additional stuff' } + ] + ms.addAll(documents) + await ms.vacuum({ batchSize: ms.termCount + 2 }) + expect(ms.isVacuuming).toEqual(false) + }) }) describe('addAll', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index b5d0be6a..e57bb782 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -896,7 +896,7 @@ export default class MiniSearch { if (this.vacuumConditionsMet(conditions)) { const batchSize = options.batchSize || defaultVacuumOptions.batchSize const batchWait = options.batchWait || defaultVacuumOptions.batchWait - let i = 0 + let i = 1 for (const [term, fieldsData] of this._index) { for (const [fieldId, fieldIndex] of fieldsData) { @@ -924,6 +924,9 @@ export default class MiniSearch { this._dirtCount -= initialDirtCount } + // Make the next lines always async, so they execute after this function returns + await null + this._currentVacuum = this._enqueuedVacuum this._enqueuedVacuum = null } From c1ffed13dc503f818a02a09e90f1073cbad74be0 Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Tue, 22 Nov 2022 13:48:55 +0100 Subject: [PATCH 17/21] Add termCount getter --- src/MiniSearch.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index e57bb782..73162154 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -1233,6 +1233,13 @@ export default class MiniSearch { return this._documentCount } + /** + * Number of terms in the index + */ + get termCount (): number { + return this._index.size + } + /** * Deserializes a JSON index (serialized with `JSON.stringify(miniSearch)`) * and instantiates a MiniSearch instance. It should be given the same options From 873100025bd330b4b4b232180f045e06207e20cd Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Tue, 22 Nov 2022 13:49:09 +0100 Subject: [PATCH 18/21] Make getDefault return autoVacuum defaults --- src/MiniSearch.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 73162154..1fa830ba 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -1764,6 +1764,11 @@ const termToQuerySpec = (options: SearchOptions) => (term: string, i: number, te return { term, fuzzy, prefix } } +const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } +const defaultVacuumConditions = { minDirtFactor: 0.15, minDirtCount: 20 } + +const defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions } + const defaultOptions = { idField: 'id', extractField: (document: any, fieldName: string) => document[fieldName], @@ -1772,7 +1777,8 @@ const defaultOptions = { fields: undefined, searchOptions: undefined, storeFields: [], - logger: (level: LogLevel, message: string, code?: string) => console != null && console.warn != null && console[level](message) + logger: (level: LogLevel, message: string, code?: string) => console != null && console.warn != null && console[level](message), + autoVacuum: defaultAutoVacuumOptions } const defaultSearchOptions = { @@ -1790,11 +1796,6 @@ const defaultAutoSuggestOptions = { i === terms.length - 1 } -const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } -const defaultVacuumConditions = { minDirtFactor: 0.15, minDirtCount: 20 } - -const defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions } - const assignUniqueTerm = (target: string[], term: string): void => { // Avoid adding duplicate terms. if (!target.includes(term)) target.push(term) From b59650c02e91bcdf17e75695ab672da4e998254c Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Tue, 22 Nov 2022 14:38:12 +0100 Subject: [PATCH 19/21] Fixes for auto vacuum default and batching --- src/MiniSearch.test.js | 11 ++++++++++- src/MiniSearch.ts | 19 +++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index a0333ee3..df949d1f 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -525,6 +525,15 @@ describe('MiniSearch', () => { expect(ms.search('stuff')).toEqual(results) }) + it('triggers auto vacuum by default', () => { + const ms = new MiniSearch({ fields: ['text'] }) + ms.add({ id: 1, text: 'Some stuff' }) + ms._dirtCount = 1000 + + ms.discard(1) + expect(ms.isVacuuming).toEqual(true) + }) + it('triggers auto vacuum when the threshold is met', () => { const ms = new MiniSearch({ fields: ['text'], @@ -783,7 +792,7 @@ describe('MiniSearch', () => { { id: 2, text: 'Some additional stuff' } ] ms.addAll(documents) - await ms.vacuum({ batchSize: ms.termCount + 2 }) + await ms.vacuum({ batchSize: ms.termCount + 1 }) expect(ms.isVacuuming).toEqual(false) }) }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 1fa830ba..ec5460de 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -527,10 +527,12 @@ export default class MiniSearch { throw new Error('MiniSearch: option "fields" must be provided') } + const autoVacuum = (options.autoVacuum == null || options.autoVacuum === true) ? defaultAutoVacuumOptions : options.autoVacuum + this._options = { ...defaultOptions, ...options, - autoVacuum: !!options.autoVacuum && (options.autoVacuum === true ? defaultAutoVacuumOptions : options.autoVacuum), + autoVacuum, searchOptions: { ...defaultSearchOptions, ...(options.searchOptions || {}) }, autoSuggestOptions: { ...defaultAutoSuggestOptions, ...(options.autoSuggestOptions || {}) } } @@ -915,10 +917,11 @@ export default class MiniSearch { this._index.delete(term) } - i += 1 if (i % batchSize === 0) { await new Promise((resolve) => setTimeout(resolve, batchWait)) } + + i += 1 } this._dirtCount -= initialDirtCount @@ -1764,11 +1767,6 @@ const termToQuerySpec = (options: SearchOptions) => (term: string, i: number, te return { term, fuzzy, prefix } } -const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } -const defaultVacuumConditions = { minDirtFactor: 0.15, minDirtCount: 20 } - -const defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions } - const defaultOptions = { idField: 'id', extractField: (document: any, fieldName: string) => document[fieldName], @@ -1778,7 +1776,7 @@ const defaultOptions = { searchOptions: undefined, storeFields: [], logger: (level: LogLevel, message: string, code?: string) => console != null && console.warn != null && console[level](message), - autoVacuum: defaultAutoVacuumOptions + autoVacuum: true } const defaultSearchOptions = { @@ -1796,6 +1794,11 @@ const defaultAutoSuggestOptions = { i === terms.length - 1 } +const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } +const defaultVacuumConditions = { minDirtFactor: 0.15, minDirtCount: 20 } + +const defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions } + const assignUniqueTerm = (target: string[], term: string): void => { // Avoid adding duplicate terms. if (!target.includes(term)) target.push(term) From 732d95a576a4227d63b309facb553e2e184c98ca Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Wed, 23 Nov 2022 12:20:21 +0100 Subject: [PATCH 20/21] Improve documentation --- docs/assets/js/search.json | 2 +- docs/classes/_minisearch_.minisearch.html | 389 ++++++++++++++++-- ...hablemap_searchablemap_.searchablemap.html | 36 +- docs/examples/app.js | 10 +- docs/examples/billboard_1965-2015.json.gz | Bin 92024 -> 92024 bytes docs/modules/_minisearch_.html | 145 ++++++- src/MiniSearch.ts | 216 +++++----- 7 files changed, 638 insertions(+), 160 deletions(-) diff --git a/docs/assets/js/search.json b/docs/assets/js/search.json index 17bbf798..6e5f1438 100644 --- a/docs/assets/js/search.json +++ b/docs/assets/js/search.json @@ -1 +1 @@ -{"kinds":{"1":"Module","32":"Variable","128":"Class","512":"Constructor","2048":"Method","65536":"Type literal","262144":"Accessor","4194304":"Type alias"},"rows":[{"id":0,"kind":1,"name":"\"SearchableMap/SearchableMap\"","url":"modules/_searchablemap_searchablemap_.html","classes":"tsd-kind-module"},{"id":1,"kind":128,"name":"SearchableMap","url":"classes/_searchablemap_searchablemap_.searchablemap.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"SearchableMap/SearchableMap\""},{"id":2,"kind":512,"name":"constructor","url":"classes/_searchablemap_searchablemap_.searchablemap.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":3,"kind":2048,"name":"atPrefix","url":"classes/_searchablemap_searchablemap_.searchablemap.html#atprefix","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":4,"kind":2048,"name":"clear","url":"classes/_searchablemap_searchablemap_.searchablemap.html#clear","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":5,"kind":2048,"name":"delete","url":"classes/_searchablemap_searchablemap_.searchablemap.html#delete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":6,"kind":2048,"name":"entries","url":"classes/_searchablemap_searchablemap_.searchablemap.html#entries","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":7,"kind":2048,"name":"forEach","url":"classes/_searchablemap_searchablemap_.searchablemap.html#foreach","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":8,"kind":2048,"name":"fuzzyGet","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fuzzyget","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":9,"kind":2048,"name":"get","url":"classes/_searchablemap_searchablemap_.searchablemap.html#get","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":10,"kind":2048,"name":"has","url":"classes/_searchablemap_searchablemap_.searchablemap.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":11,"kind":2048,"name":"keys","url":"classes/_searchablemap_searchablemap_.searchablemap.html#keys","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":12,"kind":2048,"name":"set","url":"classes/_searchablemap_searchablemap_.searchablemap.html#set","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":13,"kind":262144,"name":"size","url":"classes/_searchablemap_searchablemap_.searchablemap.html#size","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":14,"kind":2048,"name":"update","url":"classes/_searchablemap_searchablemap_.searchablemap.html#update","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":15,"kind":2048,"name":"fetch","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fetch","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":16,"kind":2048,"name":"values","url":"classes/_searchablemap_searchablemap_.searchablemap.html#values","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":17,"kind":2048,"name":"[Symbol.iterator]","url":"classes/_searchablemap_searchablemap_.searchablemap.html#_symbol_iterator_","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":18,"kind":2048,"name":"from","url":"classes/_searchablemap_searchablemap_.searchablemap.html#from","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":19,"kind":2048,"name":"fromObject","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fromobject","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":20,"kind":1,"name":"\"MiniSearch\"","url":"modules/_minisearch_.html","classes":"tsd-kind-module"},{"id":21,"kind":128,"name":"MiniSearch","url":"classes/_minisearch_.minisearch.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":22,"kind":512,"name":"constructor","url":"classes/_minisearch_.minisearch.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":23,"kind":2048,"name":"add","url":"classes/_minisearch_.minisearch.html#add","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":24,"kind":2048,"name":"addAll","url":"classes/_minisearch_.minisearch.html#addall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":25,"kind":2048,"name":"addAllAsync","url":"classes/_minisearch_.minisearch.html#addallasync","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":26,"kind":2048,"name":"remove","url":"classes/_minisearch_.minisearch.html#remove","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":27,"kind":2048,"name":"removeAll","url":"classes/_minisearch_.minisearch.html#removeall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":28,"kind":2048,"name":"search","url":"classes/_minisearch_.minisearch.html#search","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":29,"kind":2048,"name":"autoSuggest","url":"classes/_minisearch_.minisearch.html#autosuggest","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":30,"kind":262144,"name":"documentCount","url":"classes/_minisearch_.minisearch.html#documentcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":31,"kind":2048,"name":"loadJSON","url":"classes/_minisearch_.minisearch.html#loadjson","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":32,"kind":2048,"name":"getDefault","url":"classes/_minisearch_.minisearch.html#getdefault","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":33,"kind":2048,"name":"toJSON","url":"classes/_minisearch_.minisearch.html#tojson","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":34,"kind":4194304,"name":"SearchOptions","url":"modules/_minisearch_.html#searchoptions-1","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":35,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchoptions-1.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchOptions"},{"id":36,"kind":32,"name":"fields","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fields-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":37,"kind":32,"name":"filter","url":"modules/_minisearch_.html#searchoptions-1.__type-2.filter","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":38,"kind":32,"name":"boost","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boost","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":39,"kind":32,"name":"weights","url":"modules/_minisearch_.html#searchoptions-1.__type-2.weights","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":40,"kind":32,"name":"boostDocument","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boostdocument","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":41,"kind":32,"name":"prefix","url":"modules/_minisearch_.html#searchoptions-1.__type-2.prefix","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":42,"kind":32,"name":"fuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":43,"kind":32,"name":"maxFuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.maxfuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":44,"kind":32,"name":"combineWith","url":"modules/_minisearch_.html#searchoptions-1.__type-2.combinewith","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":45,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#searchoptions-1.__type-2.tokenize-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":46,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#searchoptions-1.__type-2.processterm-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":47,"kind":4194304,"name":"Options","url":"modules/_minisearch_.html#options","classes":"tsd-kind-type-alias tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":48,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#options.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Options"},{"id":49,"kind":32,"name":"fields","url":"modules/_minisearch_.html#options.__type-1.fields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":50,"kind":32,"name":"idField","url":"modules/_minisearch_.html#options.__type-1.idfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":51,"kind":32,"name":"storeFields","url":"modules/_minisearch_.html#options.__type-1.storefields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":52,"kind":32,"name":"extractField","url":"modules/_minisearch_.html#options.__type-1.extractfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":53,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#options.__type-1.tokenize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":54,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#options.__type-1.processterm","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":55,"kind":32,"name":"logger","url":"modules/_minisearch_.html#options.__type-1.logger","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":56,"kind":32,"name":"searchOptions","url":"modules/_minisearch_.html#options.__type-1.searchoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":57,"kind":32,"name":"autoSuggestOptions","url":"modules/_minisearch_.html#options.__type-1.autosuggestoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":58,"kind":4194304,"name":"Suggestion","url":"modules/_minisearch_.html#suggestion","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":59,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#suggestion.__type-4","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Suggestion"},{"id":60,"kind":32,"name":"suggestion","url":"modules/_minisearch_.html#suggestion.__type-4.suggestion-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":61,"kind":32,"name":"terms","url":"modules/_minisearch_.html#suggestion.__type-4.terms-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":62,"kind":32,"name":"score","url":"modules/_minisearch_.html#suggestion.__type-4.score-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":63,"kind":4194304,"name":"MatchInfo","url":"modules/_minisearch_.html#matchinfo","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":64,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#matchinfo.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".MatchInfo"},{"id":65,"kind":4194304,"name":"SearchResult","url":"modules/_minisearch_.html#searchresult","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":66,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchresult.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchResult"},{"id":67,"kind":32,"name":"id","url":"modules/_minisearch_.html#searchresult.__type-3.id","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":68,"kind":32,"name":"terms","url":"modules/_minisearch_.html#searchresult.__type-3.terms","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":69,"kind":32,"name":"score","url":"modules/_minisearch_.html#searchresult.__type-3.score","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":70,"kind":32,"name":"match","url":"modules/_minisearch_.html#searchresult.__type-3.match","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":71,"kind":4194304,"name":"QueryCombination","url":"modules/_minisearch_.html#querycombination","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":72,"kind":4194304,"name":"Query","url":"modules/_minisearch_.html#query","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,33.878]],["parent/0",[]],["name/1",[1,38.986]],["parent/1",[0,3.349]],["name/2",[2,33.878]],["parent/2",[3,1.371]],["name/3",[4,38.986]],["parent/3",[3,1.371]],["name/4",[5,38.986]],["parent/4",[3,1.371]],["name/5",[6,38.986]],["parent/5",[3,1.371]],["name/6",[7,38.986]],["parent/6",[3,1.371]],["name/7",[8,38.986]],["parent/7",[3,1.371]],["name/8",[9,38.986]],["parent/8",[3,1.371]],["name/9",[10,38.986]],["parent/9",[3,1.371]],["name/10",[11,38.986]],["parent/10",[3,1.371]],["name/11",[12,38.986]],["parent/11",[3,1.371]],["name/12",[13,38.986]],["parent/12",[3,1.371]],["name/13",[14,38.986]],["parent/13",[3,1.371]],["name/14",[15,38.986]],["parent/14",[3,1.371]],["name/15",[16,38.986]],["parent/15",[3,1.371]],["name/16",[17,38.986]],["parent/16",[3,1.371]],["name/17",[18,38.986]],["parent/17",[3,1.371]],["name/18",[19,38.986]],["parent/18",[3,1.371]],["name/19",[20,38.986]],["parent/19",[3,1.371]],["name/20",[21,19.527]],["parent/20",[]],["name/21",[21,19.527]],["parent/21",[21,1.93]],["name/22",[2,33.878]],["parent/22",[22,1.758]],["name/23",[23,38.986]],["parent/23",[22,1.758]],["name/24",[24,38.986]],["parent/24",[22,1.758]],["name/25",[25,38.986]],["parent/25",[22,1.758]],["name/26",[26,38.986]],["parent/26",[22,1.758]],["name/27",[27,38.986]],["parent/27",[22,1.758]],["name/28",[28,38.986]],["parent/28",[22,1.758]],["name/29",[29,38.986]],["parent/29",[22,1.758]],["name/30",[30,38.986]],["parent/30",[22,1.758]],["name/31",[31,38.986]],["parent/31",[22,1.758]],["name/32",[32,38.986]],["parent/32",[22,1.758]],["name/33",[33,38.986]],["parent/33",[22,1.758]],["name/34",[34,33.878]],["parent/34",[21,1.93]],["name/35",[35,25.993]],["parent/35",[36,3.854]],["name/36",[37,33.878]],["parent/36",[38,1.841]],["name/37",[39,38.986]],["parent/37",[38,1.841]],["name/38",[40,38.986]],["parent/38",[38,1.841]],["name/39",[41,38.986]],["parent/39",[38,1.841]],["name/40",[42,38.986]],["parent/40",[38,1.841]],["name/41",[43,38.986]],["parent/41",[38,1.841]],["name/42",[44,38.986]],["parent/42",[38,1.841]],["name/43",[45,38.986]],["parent/43",[38,1.841]],["name/44",[46,38.986]],["parent/44",[38,1.841]],["name/45",[47,33.878]],["parent/45",[38,1.841]],["name/46",[48,33.878]],["parent/46",[38,1.841]],["name/47",[49,38.986]],["parent/47",[21,1.93]],["name/48",[35,25.993]],["parent/48",[50,3.854]],["name/49",[37,33.878]],["parent/49",[51,2.029]],["name/50",[52,38.986]],["parent/50",[51,2.029]],["name/51",[53,38.986]],["parent/51",[51,2.029]],["name/52",[54,38.986]],["parent/52",[51,2.029]],["name/53",[47,33.878]],["parent/53",[51,2.029]],["name/54",[48,33.878]],["parent/54",[51,2.029]],["name/55",[55,38.986]],["parent/55",[51,2.029]],["name/56",[34,33.878]],["parent/56",[51,2.029]],["name/57",[56,38.986]],["parent/57",[51,2.029]],["name/58",[57,33.878]],["parent/58",[21,1.93]],["name/59",[35,25.993]],["parent/59",[58,3.854]],["name/60",[57,33.878]],["parent/60",[59,3.017]],["name/61",[60,33.878]],["parent/61",[59,3.017]],["name/62",[61,33.878]],["parent/62",[59,3.017]],["name/63",[62,38.986]],["parent/63",[21,1.93]],["name/64",[35,25.993]],["parent/64",[63,3.854]],["name/65",[64,38.986]],["parent/65",[21,1.93]],["name/66",[35,25.993]],["parent/66",[65,3.854]],["name/67",[66,38.986]],["parent/67",[67,2.768]],["name/68",[60,33.878]],["parent/68",[67,2.768]],["name/69",[61,33.878]],["parent/69",[67,2.768]],["name/70",[68,38.986]],["parent/70",[67,2.768]],["name/71",[69,38.986]],["parent/71",[21,1.93]],["name/72",[70,38.986]],["parent/72",[21,1.93]]],"invertedIndex":[["__type",{"_index":35,"name":{"35":{},"48":{},"59":{},"64":{},"66":{}},"parent":{}}],["add",{"_index":23,"name":{"23":{}},"parent":{}}],["addall",{"_index":24,"name":{"24":{}},"parent":{}}],["addallasync",{"_index":25,"name":{"25":{}},"parent":{}}],["atprefix",{"_index":4,"name":{"3":{}},"parent":{}}],["autosuggest",{"_index":29,"name":{"29":{}},"parent":{}}],["autosuggestoptions",{"_index":56,"name":{"57":{}},"parent":{}}],["boost",{"_index":40,"name":{"38":{}},"parent":{}}],["boostdocument",{"_index":42,"name":{"40":{}},"parent":{}}],["clear",{"_index":5,"name":{"4":{}},"parent":{}}],["combinewith",{"_index":46,"name":{"44":{}},"parent":{}}],["constructor",{"_index":2,"name":{"2":{},"22":{}},"parent":{}}],["delete",{"_index":6,"name":{"5":{}},"parent":{}}],["documentcount",{"_index":30,"name":{"30":{}},"parent":{}}],["entries",{"_index":7,"name":{"6":{}},"parent":{}}],["extractfield",{"_index":54,"name":{"52":{}},"parent":{}}],["fetch",{"_index":16,"name":{"15":{}},"parent":{}}],["fields",{"_index":37,"name":{"36":{},"49":{}},"parent":{}}],["filter",{"_index":39,"name":{"37":{}},"parent":{}}],["foreach",{"_index":8,"name":{"7":{}},"parent":{}}],["from",{"_index":19,"name":{"18":{}},"parent":{}}],["fromobject",{"_index":20,"name":{"19":{}},"parent":{}}],["fuzzy",{"_index":44,"name":{"42":{}},"parent":{}}],["fuzzyget",{"_index":9,"name":{"8":{}},"parent":{}}],["get",{"_index":10,"name":{"9":{}},"parent":{}}],["getdefault",{"_index":32,"name":{"32":{}},"parent":{}}],["has",{"_index":11,"name":{"10":{}},"parent":{}}],["id",{"_index":66,"name":{"67":{}},"parent":{}}],["idfield",{"_index":52,"name":{"50":{}},"parent":{}}],["keys",{"_index":12,"name":{"11":{}},"parent":{}}],["loadjson",{"_index":31,"name":{"31":{}},"parent":{}}],["logger",{"_index":55,"name":{"55":{}},"parent":{}}],["match",{"_index":68,"name":{"70":{}},"parent":{}}],["matchinfo",{"_index":62,"name":{"63":{}},"parent":{}}],["maxfuzzy",{"_index":45,"name":{"43":{}},"parent":{}}],["minisearch",{"_index":21,"name":{"20":{},"21":{}},"parent":{"21":{},"34":{},"47":{},"58":{},"63":{},"65":{},"71":{},"72":{}}}],["minisearch\".matchinfo",{"_index":63,"name":{},"parent":{"64":{}}}],["minisearch\".minisearch",{"_index":22,"name":{},"parent":{"22":{},"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"31":{},"32":{},"33":{}}}],["minisearch\".options",{"_index":50,"name":{},"parent":{"48":{}}}],["minisearch\".options.__type",{"_index":51,"name":{},"parent":{"49":{},"50":{},"51":{},"52":{},"53":{},"54":{},"55":{},"56":{},"57":{}}}],["minisearch\".searchoptions",{"_index":36,"name":{},"parent":{"35":{}}}],["minisearch\".searchoptions.__type",{"_index":38,"name":{},"parent":{"36":{},"37":{},"38":{},"39":{},"40":{},"41":{},"42":{},"43":{},"44":{},"45":{},"46":{}}}],["minisearch\".searchresult",{"_index":65,"name":{},"parent":{"66":{}}}],["minisearch\".searchresult.__type",{"_index":67,"name":{},"parent":{"67":{},"68":{},"69":{},"70":{}}}],["minisearch\".suggestion",{"_index":58,"name":{},"parent":{"59":{}}}],["minisearch\".suggestion.__type",{"_index":59,"name":{},"parent":{"60":{},"61":{},"62":{}}}],["options",{"_index":49,"name":{"47":{}},"parent":{}}],["prefix",{"_index":43,"name":{"41":{}},"parent":{}}],["processterm",{"_index":48,"name":{"46":{},"54":{}},"parent":{}}],["query",{"_index":70,"name":{"72":{}},"parent":{}}],["querycombination",{"_index":69,"name":{"71":{}},"parent":{}}],["remove",{"_index":26,"name":{"26":{}},"parent":{}}],["removeall",{"_index":27,"name":{"27":{}},"parent":{}}],["score",{"_index":61,"name":{"62":{},"69":{}},"parent":{}}],["search",{"_index":28,"name":{"28":{}},"parent":{}}],["searchablemap",{"_index":1,"name":{"1":{}},"parent":{}}],["searchablemap/searchablemap",{"_index":0,"name":{"0":{}},"parent":{"1":{}}}],["searchablemap/searchablemap\".searchablemap",{"_index":3,"name":{},"parent":{"2":{},"3":{},"4":{},"5":{},"6":{},"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{}}}],["searchoptions",{"_index":34,"name":{"34":{},"56":{}},"parent":{}}],["searchresult",{"_index":64,"name":{"65":{}},"parent":{}}],["set",{"_index":13,"name":{"12":{}},"parent":{}}],["size",{"_index":14,"name":{"13":{}},"parent":{}}],["storefields",{"_index":53,"name":{"51":{}},"parent":{}}],["suggestion",{"_index":57,"name":{"58":{},"60":{}},"parent":{}}],["symbol.iterator",{"_index":18,"name":{"17":{}},"parent":{}}],["terms",{"_index":60,"name":{"61":{},"68":{}},"parent":{}}],["tojson",{"_index":33,"name":{"33":{}},"parent":{}}],["tokenize",{"_index":47,"name":{"45":{},"53":{}},"parent":{}}],["update",{"_index":15,"name":{"14":{}},"parent":{}}],["values",{"_index":17,"name":{"16":{}},"parent":{}}],["weights",{"_index":41,"name":{"39":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file +{"kinds":{"1":"Module","32":"Variable","128":"Class","512":"Constructor","2048":"Method","65536":"Type literal","262144":"Accessor","4194304":"Type alias"},"rows":[{"id":0,"kind":1,"name":"\"SearchableMap/SearchableMap\"","url":"modules/_searchablemap_searchablemap_.html","classes":"tsd-kind-module"},{"id":1,"kind":128,"name":"SearchableMap","url":"classes/_searchablemap_searchablemap_.searchablemap.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"SearchableMap/SearchableMap\""},{"id":2,"kind":512,"name":"constructor","url":"classes/_searchablemap_searchablemap_.searchablemap.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":3,"kind":2048,"name":"atPrefix","url":"classes/_searchablemap_searchablemap_.searchablemap.html#atprefix","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":4,"kind":2048,"name":"clear","url":"classes/_searchablemap_searchablemap_.searchablemap.html#clear","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":5,"kind":2048,"name":"delete","url":"classes/_searchablemap_searchablemap_.searchablemap.html#delete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":6,"kind":2048,"name":"entries","url":"classes/_searchablemap_searchablemap_.searchablemap.html#entries","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":7,"kind":2048,"name":"forEach","url":"classes/_searchablemap_searchablemap_.searchablemap.html#foreach","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":8,"kind":2048,"name":"fuzzyGet","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fuzzyget","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":9,"kind":2048,"name":"get","url":"classes/_searchablemap_searchablemap_.searchablemap.html#get","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":10,"kind":2048,"name":"has","url":"classes/_searchablemap_searchablemap_.searchablemap.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":11,"kind":2048,"name":"keys","url":"classes/_searchablemap_searchablemap_.searchablemap.html#keys","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":12,"kind":2048,"name":"set","url":"classes/_searchablemap_searchablemap_.searchablemap.html#set","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":13,"kind":262144,"name":"size","url":"classes/_searchablemap_searchablemap_.searchablemap.html#size","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":14,"kind":2048,"name":"update","url":"classes/_searchablemap_searchablemap_.searchablemap.html#update","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":15,"kind":2048,"name":"fetch","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fetch","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":16,"kind":2048,"name":"values","url":"classes/_searchablemap_searchablemap_.searchablemap.html#values","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":17,"kind":2048,"name":"[Symbol.iterator]","url":"classes/_searchablemap_searchablemap_.searchablemap.html#_symbol_iterator_","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":18,"kind":2048,"name":"from","url":"classes/_searchablemap_searchablemap_.searchablemap.html#from","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":19,"kind":2048,"name":"fromObject","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fromobject","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":20,"kind":1,"name":"\"MiniSearch\"","url":"modules/_minisearch_.html","classes":"tsd-kind-module"},{"id":21,"kind":128,"name":"MiniSearch","url":"classes/_minisearch_.minisearch.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":22,"kind":512,"name":"constructor","url":"classes/_minisearch_.minisearch.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":23,"kind":2048,"name":"add","url":"classes/_minisearch_.minisearch.html#add","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":24,"kind":2048,"name":"addAll","url":"classes/_minisearch_.minisearch.html#addall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":25,"kind":2048,"name":"addAllAsync","url":"classes/_minisearch_.minisearch.html#addallasync","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":26,"kind":2048,"name":"remove","url":"classes/_minisearch_.minisearch.html#remove","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":27,"kind":2048,"name":"removeAll","url":"classes/_minisearch_.minisearch.html#removeall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":28,"kind":2048,"name":"discard","url":"classes/_minisearch_.minisearch.html#discard","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":29,"kind":2048,"name":"replace","url":"classes/_minisearch_.minisearch.html#replace","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":30,"kind":2048,"name":"vacuum","url":"classes/_minisearch_.minisearch.html#vacuum","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":31,"kind":262144,"name":"isVacuuming","url":"classes/_minisearch_.minisearch.html#isvacuuming","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":32,"kind":262144,"name":"dirtCount","url":"classes/_minisearch_.minisearch.html#dirtcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":33,"kind":262144,"name":"dirtFactor","url":"classes/_minisearch_.minisearch.html#dirtfactor","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":34,"kind":2048,"name":"has","url":"classes/_minisearch_.minisearch.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":35,"kind":2048,"name":"search","url":"classes/_minisearch_.minisearch.html#search","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":36,"kind":2048,"name":"autoSuggest","url":"classes/_minisearch_.minisearch.html#autosuggest","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":37,"kind":262144,"name":"documentCount","url":"classes/_minisearch_.minisearch.html#documentcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":38,"kind":262144,"name":"termCount","url":"classes/_minisearch_.minisearch.html#termcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":39,"kind":2048,"name":"loadJSON","url":"classes/_minisearch_.minisearch.html#loadjson","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":40,"kind":2048,"name":"getDefault","url":"classes/_minisearch_.minisearch.html#getdefault","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":41,"kind":2048,"name":"toJSON","url":"classes/_minisearch_.minisearch.html#tojson","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":42,"kind":4194304,"name":"SearchOptions","url":"modules/_minisearch_.html#searchoptions-1","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":43,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchoptions-1.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchOptions"},{"id":44,"kind":32,"name":"fields","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fields-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":45,"kind":32,"name":"filter","url":"modules/_minisearch_.html#searchoptions-1.__type-2.filter","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":46,"kind":32,"name":"boost","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boost","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":47,"kind":32,"name":"weights","url":"modules/_minisearch_.html#searchoptions-1.__type-2.weights","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":48,"kind":32,"name":"boostDocument","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boostdocument","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":49,"kind":32,"name":"prefix","url":"modules/_minisearch_.html#searchoptions-1.__type-2.prefix","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":50,"kind":32,"name":"fuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":51,"kind":32,"name":"maxFuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.maxfuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":52,"kind":32,"name":"combineWith","url":"modules/_minisearch_.html#searchoptions-1.__type-2.combinewith","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":53,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#searchoptions-1.__type-2.tokenize-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":54,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#searchoptions-1.__type-2.processterm-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":55,"kind":4194304,"name":"Options","url":"modules/_minisearch_.html#options","classes":"tsd-kind-type-alias tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":56,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#options.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Options"},{"id":57,"kind":32,"name":"fields","url":"modules/_minisearch_.html#options.__type-1.fields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":58,"kind":32,"name":"idField","url":"modules/_minisearch_.html#options.__type-1.idfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":59,"kind":32,"name":"storeFields","url":"modules/_minisearch_.html#options.__type-1.storefields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":60,"kind":32,"name":"extractField","url":"modules/_minisearch_.html#options.__type-1.extractfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":61,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#options.__type-1.tokenize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":62,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#options.__type-1.processterm","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":63,"kind":32,"name":"logger","url":"modules/_minisearch_.html#options.__type-1.logger","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":64,"kind":32,"name":"autoVacuum","url":"modules/_minisearch_.html#options.__type-1.autovacuum","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":65,"kind":32,"name":"searchOptions","url":"modules/_minisearch_.html#options.__type-1.searchoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":66,"kind":32,"name":"autoSuggestOptions","url":"modules/_minisearch_.html#options.__type-1.autosuggestoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":67,"kind":4194304,"name":"Suggestion","url":"modules/_minisearch_.html#suggestion","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":68,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#suggestion.__type-4","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Suggestion"},{"id":69,"kind":32,"name":"suggestion","url":"modules/_minisearch_.html#suggestion.__type-4.suggestion-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":70,"kind":32,"name":"terms","url":"modules/_minisearch_.html#suggestion.__type-4.terms-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":71,"kind":32,"name":"score","url":"modules/_minisearch_.html#suggestion.__type-4.score-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":72,"kind":4194304,"name":"MatchInfo","url":"modules/_minisearch_.html#matchinfo","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":73,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#matchinfo.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".MatchInfo"},{"id":74,"kind":4194304,"name":"SearchResult","url":"modules/_minisearch_.html#searchresult","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":75,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchresult.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchResult"},{"id":76,"kind":32,"name":"id","url":"modules/_minisearch_.html#searchresult.__type-3.id","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":77,"kind":32,"name":"terms","url":"modules/_minisearch_.html#searchresult.__type-3.terms","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":78,"kind":32,"name":"score","url":"modules/_minisearch_.html#searchresult.__type-3.score","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":79,"kind":32,"name":"match","url":"modules/_minisearch_.html#searchresult.__type-3.match","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":80,"kind":4194304,"name":"QueryCombination","url":"modules/_minisearch_.html#querycombination","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":81,"kind":4194304,"name":"Query","url":"modules/_minisearch_.html#query","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":82,"kind":4194304,"name":"VacuumOptions","url":"modules/_minisearch_.html#vacuumoptions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":83,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#vacuumoptions.__type-6","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".VacuumOptions"},{"id":84,"kind":32,"name":"batchSize","url":"modules/_minisearch_.html#vacuumoptions.__type-6.batchsize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumOptions.__type"},{"id":85,"kind":32,"name":"batchWait","url":"modules/_minisearch_.html#vacuumoptions.__type-6.batchwait","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumOptions.__type"},{"id":86,"kind":4194304,"name":"VacuumConditions","url":"modules/_minisearch_.html#vacuumconditions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":87,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#vacuumconditions.__type-5","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".VacuumConditions"},{"id":88,"kind":32,"name":"minDirtCount","url":"modules/_minisearch_.html#vacuumconditions.__type-5.mindirtcount","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumConditions.__type"},{"id":89,"kind":32,"name":"minDirtFactor","url":"modules/_minisearch_.html#vacuumconditions.__type-5.mindirtfactor","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumConditions.__type"},{"id":90,"kind":4194304,"name":"AutoVacuumOptions","url":"modules/_minisearch_.html#autovacuumoptions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,36.055]],["parent/0",[]],["name/1",[1,41.163]],["parent/1",[0,3.573]],["name/2",[2,36.055]],["parent/2",[3,1.589]],["name/3",[4,41.163]],["parent/3",[3,1.589]],["name/4",[5,41.163]],["parent/4",[3,1.589]],["name/5",[6,41.163]],["parent/5",[3,1.589]],["name/6",[7,41.163]],["parent/6",[3,1.589]],["name/7",[8,41.163]],["parent/7",[3,1.589]],["name/8",[9,41.163]],["parent/8",[3,1.589]],["name/9",[10,41.163]],["parent/9",[3,1.589]],["name/10",[11,36.055]],["parent/10",[3,1.589]],["name/11",[12,41.163]],["parent/11",[3,1.589]],["name/12",[13,41.163]],["parent/12",[3,1.589]],["name/13",[14,41.163]],["parent/13",[3,1.589]],["name/14",[15,41.163]],["parent/14",[3,1.589]],["name/15",[16,41.163]],["parent/15",[3,1.589]],["name/16",[17,41.163]],["parent/16",[3,1.589]],["name/17",[18,41.163]],["parent/17",[3,1.589]],["name/18",[19,41.163]],["parent/18",[3,1.589]],["name/19",[20,41.163]],["parent/19",[3,1.589]],["name/20",[21,19.191]],["parent/20",[]],["name/21",[21,19.191]],["parent/21",[21,1.902]],["name/22",[2,36.055]],["parent/22",[22,1.488]],["name/23",[23,41.163]],["parent/23",[22,1.488]],["name/24",[24,41.163]],["parent/24",[22,1.488]],["name/25",[25,41.163]],["parent/25",[22,1.488]],["name/26",[26,41.163]],["parent/26",[22,1.488]],["name/27",[27,41.163]],["parent/27",[22,1.488]],["name/28",[28,41.163]],["parent/28",[22,1.488]],["name/29",[29,41.163]],["parent/29",[22,1.488]],["name/30",[30,41.163]],["parent/30",[22,1.488]],["name/31",[31,41.163]],["parent/31",[22,1.488]],["name/32",[32,41.163]],["parent/32",[22,1.488]],["name/33",[33,41.163]],["parent/33",[22,1.488]],["name/34",[11,36.055]],["parent/34",[22,1.488]],["name/35",[34,41.163]],["parent/35",[22,1.488]],["name/36",[35,41.163]],["parent/36",[22,1.488]],["name/37",[36,41.163]],["parent/37",[22,1.488]],["name/38",[37,41.163]],["parent/38",[22,1.488]],["name/39",[38,41.163]],["parent/39",[22,1.488]],["name/40",[39,41.163]],["parent/40",[22,1.488]],["name/41",[40,41.163]],["parent/41",[22,1.488]],["name/42",[41,36.055]],["parent/42",[21,1.902]],["name/43",[42,25.069]],["parent/43",[43,4.079]],["name/44",[44,36.055]],["parent/44",[45,2.06]],["name/45",[46,41.163]],["parent/45",[45,2.06]],["name/46",[47,41.163]],["parent/46",[45,2.06]],["name/47",[48,41.163]],["parent/47",[45,2.06]],["name/48",[49,41.163]],["parent/48",[45,2.06]],["name/49",[50,41.163]],["parent/49",[45,2.06]],["name/50",[51,41.163]],["parent/50",[45,2.06]],["name/51",[52,41.163]],["parent/51",[45,2.06]],["name/52",[53,41.163]],["parent/52",[45,2.06]],["name/53",[54,36.055]],["parent/53",[45,2.06]],["name/54",[55,36.055]],["parent/54",[45,2.06]],["name/55",[56,41.163]],["parent/55",[21,1.902]],["name/56",[42,25.069]],["parent/56",[57,4.079]],["name/57",[44,36.055]],["parent/57",[58,2.151]],["name/58",[59,41.163]],["parent/58",[58,2.151]],["name/59",[60,41.163]],["parent/59",[58,2.151]],["name/60",[61,41.163]],["parent/60",[58,2.151]],["name/61",[54,36.055]],["parent/61",[58,2.151]],["name/62",[55,36.055]],["parent/62",[58,2.151]],["name/63",[62,41.163]],["parent/63",[58,2.151]],["name/64",[63,41.163]],["parent/64",[58,2.151]],["name/65",[41,36.055]],["parent/65",[58,2.151]],["name/66",[64,41.163]],["parent/66",[58,2.151]],["name/67",[65,36.055]],["parent/67",[21,1.902]],["name/68",[42,25.069]],["parent/68",[66,4.079]],["name/69",[65,36.055]],["parent/69",[67,3.239]],["name/70",[68,36.055]],["parent/70",[67,3.239]],["name/71",[69,36.055]],["parent/71",[67,3.239]],["name/72",[70,41.163]],["parent/72",[21,1.902]],["name/73",[42,25.069]],["parent/73",[71,4.079]],["name/74",[72,41.163]],["parent/74",[21,1.902]],["name/75",[42,25.069]],["parent/75",[73,4.079]],["name/76",[74,41.163]],["parent/76",[75,2.99]],["name/77",[68,36.055]],["parent/77",[75,2.99]],["name/78",[69,36.055]],["parent/78",[75,2.99]],["name/79",[76,41.163]],["parent/79",[75,2.99]],["name/80",[77,41.163]],["parent/80",[21,1.902]],["name/81",[78,41.163]],["parent/81",[21,1.902]],["name/82",[79,41.163]],["parent/82",[21,1.902]],["name/83",[42,25.069]],["parent/83",[80,4.079]],["name/84",[81,41.163]],["parent/84",[82,3.573]],["name/85",[83,41.163]],["parent/85",[82,3.573]],["name/86",[84,41.163]],["parent/86",[21,1.902]],["name/87",[42,25.069]],["parent/87",[85,4.079]],["name/88",[86,41.163]],["parent/88",[87,3.573]],["name/89",[88,41.163]],["parent/89",[87,3.573]],["name/90",[89,41.163]],["parent/90",[21,1.902]]],"invertedIndex":[["__type",{"_index":42,"name":{"43":{},"56":{},"68":{},"73":{},"75":{},"83":{},"87":{}},"parent":{}}],["add",{"_index":23,"name":{"23":{}},"parent":{}}],["addall",{"_index":24,"name":{"24":{}},"parent":{}}],["addallasync",{"_index":25,"name":{"25":{}},"parent":{}}],["atprefix",{"_index":4,"name":{"3":{}},"parent":{}}],["autosuggest",{"_index":35,"name":{"36":{}},"parent":{}}],["autosuggestoptions",{"_index":64,"name":{"66":{}},"parent":{}}],["autovacuum",{"_index":63,"name":{"64":{}},"parent":{}}],["autovacuumoptions",{"_index":89,"name":{"90":{}},"parent":{}}],["batchsize",{"_index":81,"name":{"84":{}},"parent":{}}],["batchwait",{"_index":83,"name":{"85":{}},"parent":{}}],["boost",{"_index":47,"name":{"46":{}},"parent":{}}],["boostdocument",{"_index":49,"name":{"48":{}},"parent":{}}],["clear",{"_index":5,"name":{"4":{}},"parent":{}}],["combinewith",{"_index":53,"name":{"52":{}},"parent":{}}],["constructor",{"_index":2,"name":{"2":{},"22":{}},"parent":{}}],["delete",{"_index":6,"name":{"5":{}},"parent":{}}],["dirtcount",{"_index":32,"name":{"32":{}},"parent":{}}],["dirtfactor",{"_index":33,"name":{"33":{}},"parent":{}}],["discard",{"_index":28,"name":{"28":{}},"parent":{}}],["documentcount",{"_index":36,"name":{"37":{}},"parent":{}}],["entries",{"_index":7,"name":{"6":{}},"parent":{}}],["extractfield",{"_index":61,"name":{"60":{}},"parent":{}}],["fetch",{"_index":16,"name":{"15":{}},"parent":{}}],["fields",{"_index":44,"name":{"44":{},"57":{}},"parent":{}}],["filter",{"_index":46,"name":{"45":{}},"parent":{}}],["foreach",{"_index":8,"name":{"7":{}},"parent":{}}],["from",{"_index":19,"name":{"18":{}},"parent":{}}],["fromobject",{"_index":20,"name":{"19":{}},"parent":{}}],["fuzzy",{"_index":51,"name":{"50":{}},"parent":{}}],["fuzzyget",{"_index":9,"name":{"8":{}},"parent":{}}],["get",{"_index":10,"name":{"9":{}},"parent":{}}],["getdefault",{"_index":39,"name":{"40":{}},"parent":{}}],["has",{"_index":11,"name":{"10":{},"34":{}},"parent":{}}],["id",{"_index":74,"name":{"76":{}},"parent":{}}],["idfield",{"_index":59,"name":{"58":{}},"parent":{}}],["isvacuuming",{"_index":31,"name":{"31":{}},"parent":{}}],["keys",{"_index":12,"name":{"11":{}},"parent":{}}],["loadjson",{"_index":38,"name":{"39":{}},"parent":{}}],["logger",{"_index":62,"name":{"63":{}},"parent":{}}],["match",{"_index":76,"name":{"79":{}},"parent":{}}],["matchinfo",{"_index":70,"name":{"72":{}},"parent":{}}],["maxfuzzy",{"_index":52,"name":{"51":{}},"parent":{}}],["mindirtcount",{"_index":86,"name":{"88":{}},"parent":{}}],["mindirtfactor",{"_index":88,"name":{"89":{}},"parent":{}}],["minisearch",{"_index":21,"name":{"20":{},"21":{}},"parent":{"21":{},"42":{},"55":{},"67":{},"72":{},"74":{},"80":{},"81":{},"82":{},"86":{},"90":{}}}],["minisearch\".matchinfo",{"_index":71,"name":{},"parent":{"73":{}}}],["minisearch\".minisearch",{"_index":22,"name":{},"parent":{"22":{},"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"31":{},"32":{},"33":{},"34":{},"35":{},"36":{},"37":{},"38":{},"39":{},"40":{},"41":{}}}],["minisearch\".options",{"_index":57,"name":{},"parent":{"56":{}}}],["minisearch\".options.__type",{"_index":58,"name":{},"parent":{"57":{},"58":{},"59":{},"60":{},"61":{},"62":{},"63":{},"64":{},"65":{},"66":{}}}],["minisearch\".searchoptions",{"_index":43,"name":{},"parent":{"43":{}}}],["minisearch\".searchoptions.__type",{"_index":45,"name":{},"parent":{"44":{},"45":{},"46":{},"47":{},"48":{},"49":{},"50":{},"51":{},"52":{},"53":{},"54":{}}}],["minisearch\".searchresult",{"_index":73,"name":{},"parent":{"75":{}}}],["minisearch\".searchresult.__type",{"_index":75,"name":{},"parent":{"76":{},"77":{},"78":{},"79":{}}}],["minisearch\".suggestion",{"_index":66,"name":{},"parent":{"68":{}}}],["minisearch\".suggestion.__type",{"_index":67,"name":{},"parent":{"69":{},"70":{},"71":{}}}],["minisearch\".vacuumconditions",{"_index":85,"name":{},"parent":{"87":{}}}],["minisearch\".vacuumconditions.__type",{"_index":87,"name":{},"parent":{"88":{},"89":{}}}],["minisearch\".vacuumoptions",{"_index":80,"name":{},"parent":{"83":{}}}],["minisearch\".vacuumoptions.__type",{"_index":82,"name":{},"parent":{"84":{},"85":{}}}],["options",{"_index":56,"name":{"55":{}},"parent":{}}],["prefix",{"_index":50,"name":{"49":{}},"parent":{}}],["processterm",{"_index":55,"name":{"54":{},"62":{}},"parent":{}}],["query",{"_index":78,"name":{"81":{}},"parent":{}}],["querycombination",{"_index":77,"name":{"80":{}},"parent":{}}],["remove",{"_index":26,"name":{"26":{}},"parent":{}}],["removeall",{"_index":27,"name":{"27":{}},"parent":{}}],["replace",{"_index":29,"name":{"29":{}},"parent":{}}],["score",{"_index":69,"name":{"71":{},"78":{}},"parent":{}}],["search",{"_index":34,"name":{"35":{}},"parent":{}}],["searchablemap",{"_index":1,"name":{"1":{}},"parent":{}}],["searchablemap/searchablemap",{"_index":0,"name":{"0":{}},"parent":{"1":{}}}],["searchablemap/searchablemap\".searchablemap",{"_index":3,"name":{},"parent":{"2":{},"3":{},"4":{},"5":{},"6":{},"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{}}}],["searchoptions",{"_index":41,"name":{"42":{},"65":{}},"parent":{}}],["searchresult",{"_index":72,"name":{"74":{}},"parent":{}}],["set",{"_index":13,"name":{"12":{}},"parent":{}}],["size",{"_index":14,"name":{"13":{}},"parent":{}}],["storefields",{"_index":60,"name":{"59":{}},"parent":{}}],["suggestion",{"_index":65,"name":{"67":{},"69":{}},"parent":{}}],["symbol.iterator",{"_index":18,"name":{"17":{}},"parent":{}}],["termcount",{"_index":37,"name":{"38":{}},"parent":{}}],["terms",{"_index":68,"name":{"70":{},"77":{}},"parent":{}}],["tojson",{"_index":40,"name":{"41":{}},"parent":{}}],["tokenize",{"_index":54,"name":{"53":{},"61":{}},"parent":{}}],["update",{"_index":15,"name":{"14":{}},"parent":{}}],["vacuum",{"_index":30,"name":{"30":{}},"parent":{}}],["vacuumconditions",{"_index":84,"name":{"86":{}},"parent":{}}],["vacuumoptions",{"_index":79,"name":{"82":{}},"parent":{}}],["values",{"_index":17,"name":{"16":{}},"parent":{}}],["weights",{"_index":48,"name":{"47":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/docs/classes/_minisearch_.minisearch.html b/docs/classes/_minisearch_.minisearch.html index 7ec974a8..974f0c64 100644 --- a/docs/classes/_minisearch_.minisearch.html +++ b/docs/classes/_minisearch_.minisearch.html @@ -156,7 +156,11 @@

Constructors

Accessors

@@ -166,10 +170,14 @@

Methods

  • addAll
  • addAllAsync
  • autoSuggest
  • +
  • discard
  • +
  • has
  • remove
  • removeAll
  • +
  • replace
  • search
  • toJSON
  • +
  • vacuum
  • getDefault
  • loadJSON
  • @@ -189,7 +197,7 @@

    constructor

  • @@ -267,6 +275,54 @@

    Returns

    Accessors

    +
    + +

    dirtCount

    +
      +
    • get dirtCount(): number
    • +
    +
      +
    • + +
      +
      +

      The number of documents discarded since the most recent vacuuming

      +
      +
      +

      Returns number

      +
    • +
    +
    +
    + +

    dirtFactor

    +
      +
    • get dirtFactor(): number
    • +
    +
      +
    • + +
      +
      +

      A number between 0 and 1 giving an indication about the proportion of + documents that are discarded, and can therefore be cleaned up by vacuuming. + A value close to 0 means that the index is relatively clean, while a higher + value means that the index is relatively dirty, and vacuuming could release + memory.

      +
      +
      +

      Returns number

      +
    • +
    +

    documentCount

    @@ -277,12 +333,56 @@

    documentCount

  • +
    +
    +

    Total number of documents available to search

    +
    +
    +

    Returns number

    +
  • + +
    +
    + +

    isVacuuming

    +
      +
    • get isVacuuming(): boolean
    • +
    +
      +
    • + +
      +
      +

      Is true if a vacuuming operation is ongoing, false otherwise

      +
      +
      +

      Returns boolean

      +
    • +
    +
    +
    + +

    termCount

    +
      +
    • get termCount(): number
    • +
    +
      +
    • +
      -

      Number of documents in the index

      +

      Number of terms in the index

      Returns number

      @@ -302,7 +402,7 @@

      add

    • @@ -327,13 +427,13 @@

      Returns void

      addAll

        -
      • addAll(documents: T[]): void
      • +
      • addAll(documents: readonly T[]): void
      • @@ -344,7 +444,7 @@

        addAll

        Parameters

        • -
          documents: T[]
          +
          documents: readonly T[]

          An array of documents to be indexed

          @@ -358,13 +458,13 @@

          Returns void

          addAllAsync

            -
          • addAllAsync(documents: T[], options?: { chunkSize?: undefined | number }): Promise<void>
          • +
          • addAllAsync(documents: readonly T[], options?: { chunkSize?: undefined | number }): Promise<void>
          • @@ -378,7 +478,7 @@

            addAllAsync

            Parameters

            • -
              documents: T[]
              +
              documents: readonly T[]

              An array of documents to be indexed

              @@ -410,7 +510,7 @@

              autoSuggest

            • @@ -486,6 +586,109 @@

              Returns + +

              discard

              +
                +
              • discard(id: any): void
              • +
              +
                +
              • + +
                +
                +

                Discards the document with the given ID, so it won't appear in search results

                +
                +

                It has the same visible effect of MiniSearch.remove (both cause the + document to stop appearing in searches), but a different effect on the + internal data structures:

                +
                  +
                • MiniSearch.remove requires passing the full document to be removed + as argument, and removes it from the inverted index immediately.

                  +
                • +
                • MiniSearch.discard instead only needs the document ID, and works by + marking the current version of the document as discarded, so it is + immediately ignored by searches. This is faster and more convenient than + remove, but the index is not immediately modified. To take care of + that, vacuuming is performed after a certain number of documents are + discarded, cleaning up the index and allowing memory to be released.

                  +
                • +
                +

                After discarding a document, it is possible to re-add a new version, and + only the new version will appear in searches. In other words, discarding + and re-adding a document works exactly like removing and re-adding it. The + MiniSearch.replace method can also be used to replace a document with a + new version.

                + +

                Details about vacuuming

                +
                +

                Repetite calls to this method would leave obsolete document references in + the index, invisible to searches. Two mechanisms take care of cleaning up: + clean up during search, and vacuuming.

                +
                  +
                • Upon search, whenever a discarded ID is found (and ignored for the + results), references to the discarded document are removed from the + inverted index entries for the search terms. This ensures that subsequent + searches for the same terms do not need to skip these obsolete references + again.

                  +
                • +
                • In addition, vacuuming is performed automatically by default (see the + autoVacuum field in Options) after a certain number of documents + are discarded. Vacuuming traverses all terms in the index, cleaning up + all references to discarded documents. Vacuuming can also be triggered + manually by calling MiniSearch.vacuum.

                  +
                • +
                +
                +

                Parameters

                +
                  +
                • +
                  id: any
                  +
                  +

                  The ID of the document to be discarded

                  +
                  +
                • +
                +

                Returns void

                +
              • +
              +

    +
    + +

    has

    +
      +
    • has(id: any): boolean
    • +
    +
      +
    • + +
      +
      +

      Returns true if a document with the given ID is present in the index and + available for search, false otherwise

      +
      +
      +

      Parameters

      +
        +
      • +
        id: any
        +
        +

        The document ID

        +
        +
      • +
      +

      Returns boolean

      +
    • +
    +

    remove

    @@ -496,21 +699,20 @@

    remove

  • Removes the given document from the index.

    -

    The document to delete must NOT have changed between indexing and deletion, - otherwise the index will be corrupted. Therefore, when reindexing a document - after a change, the correct order of operations is:

    -
      -
    1. remove old version
    2. -
    3. apply changes
    4. -
    5. index new version
    6. -
    +

    The document to remove must NOT have changed between indexing and removal, + otherwise the index will be corrupted.

    +

    This method requires passing the full document to be removed (not just the + ID), and immediately removes the document from the inverted index, allowing + memory to be released. A convenient alternative is MiniSearch.discard, + which needs only the document ID, and has the same visible effect, but + delays cleaning up the index until the next vacuuming.

    Parameters

      @@ -529,13 +731,13 @@

      Returns void

      removeAll

        -
      • removeAll(documents?: T[]): void
      • +
      • removeAll(documents?: readonly T[]): void
      • @@ -547,7 +749,7 @@

        removeAll

        Parameters

        • -
          Optional documents: T[]
          +
          Optional documents: readonly T[]

          The documents to be removed. If this argument is omitted, all documents are removed. Note that, for removing all documents, it is @@ -560,6 +762,45 @@

          Returns void

  • +
    + +

    replace

    +
      +
    • replace(updatedDocument: T): void
    • +
    +
      +
    • + +
      +
      +

      It replaces an existing document with the given updated version

      +
      +

      It works by discarding the current version and adding the updated one, so + it is functionally equivalent to calling MiniSearch.discard followed by + MiniSearch.add. The ID of the updated document should be the same as + the original one.

      +

      Since it uses MiniSearch.discard internally, this method relies on + vacuuming to clean up obsolete document references from the index, allowing + memory to be released (see MiniSearch.discard).

      +
      +

      Parameters

      +
        +
      • +
        updatedDocument: T
        +
        +

        The updated document to replace the old version + with

        +
        +
      • +
      +

      Returns void

      +
    • +
    +

    search

    @@ -570,7 +811,7 @@

    search

  • @@ -722,7 +963,7 @@

    toJSON

  • @@ -752,6 +993,67 @@

    Returns AsPlainOb

  • +
    + +

    vacuum

    + +
      +
    • + +
      +
      +

      Triggers a manual vacuuming, cleaning up references to discarded documents + from the inverted index

      +
      +

      Vacuiuming is only useful for applications that use the + MiniSearch.discard or MiniSearch.replace methods.

      +

      By default, vacuuming is performed automatically when needed (controlled by + the autoVacuum field in Options), so there is usually no need to call + this method, unless one wants to make sure to perform vacuuming at a + specific moment.

      +

      Vacuuming traverses all terms in the inverted index in batches, and cleans + up references to discarded documents from the posting list, allowing memory + to be released.

      +

      The method takes an optional object as argument with the following keys:

      +
        +
      • batchSize: the size of each batch (1000 by default)

        +
      • +
      • batchWait: the number of milliseconds to wait between batches (10 by + default)

        +
      • +
      +

      On large indexes, vacuuming could have a non-negligible cost: batching + avoids blocking the thread for long, diluting this cost so that it is not + negatively affecting the application. Nonetheless, this method should only + be called when necessary, and relying on automatic vacuuming is usually + better.

      +

      It returns a promise that resolves (to undefined) when the clean up is + completed. If vacuuming is already ongoing at the time this method is + called, a new one is enqueued immediately after the ongoing one, and a + corresponding promise is returned. However, no more than one vacuuming is + enqueued on top of the ongoing one, even if this method is called more + times (enqueuing multiple ones would be useless).

      +
      +

      Parameters

      +
        +
      • +
        Default value options: VacuumOptions = {}
        +
        +

        Configuration options for the batch size and delay. See + VacuumOptions.

        +
        +
      • +
      +

      Returns Promise<void>

      +
    • +
    +

    Static getDefault

    @@ -762,7 +1064,7 @@

    Static getDefault

  • @@ -808,7 +1110,7 @@

    Static loadJSON

  • @@ -881,9 +1183,21 @@

    Returns constructor

  • +
  • + dirtCount +
  • +
  • + dirtFactor +
  • documentCount
  • +
  • + isVacuuming +
  • +
  • + termCount +
  • add
  • @@ -896,18 +1210,30 @@

    Returns autoSuggest

  • +
  • + discard +
  • +
  • + has +
  • remove
  • removeAll
  • +
  • + replace +
  • search
  • toJSON
  • +
  • + vacuum +
  • getDefault
  • @@ -918,6 +1244,9 @@

    Returns diff --git a/docs/classes/_searchablemap_searchablemap_.searchablemap.html b/docs/classes/_searchablemap_searchablemap_.searchablemap.html index 55598901..f5736f22 100644 --- a/docs/classes/_searchablemap_searchablemap_.searchablemap.html +++ b/docs/classes/_searchablemap_searchablemap_.searchablemap.html @@ -153,7 +153,7 @@

    constructor

  • @@ -191,7 +191,7 @@

    size

  • @@ -218,7 +218,7 @@

    [Symbol.iterator]

  • @@ -242,7 +242,7 @@

    atPrefix

  • @@ -295,7 +295,7 @@

    clear

  • @@ -319,7 +319,7 @@

    delete

  • @@ -352,7 +352,7 @@

    entries

  • @@ -377,7 +377,7 @@

    fetch

  • @@ -432,7 +432,7 @@

    forEach

  • @@ -489,7 +489,7 @@

    fuzzyGet

  • @@ -547,7 +547,7 @@

    get

  • @@ -582,7 +582,7 @@

    has

  • @@ -616,7 +616,7 @@

    keys

  • @@ -641,7 +641,7 @@

    set

  • @@ -681,7 +681,7 @@

    update

  • @@ -748,7 +748,7 @@

    values

  • @@ -773,7 +773,7 @@

    Static from

  • @@ -811,7 +811,7 @@

    Static fromObject

  • diff --git a/docs/examples/app.js b/docs/examples/app.js index 6edc69f9..cf88343f 100644 --- a/docs/examples/app.js +++ b/docs/examples/app.js @@ -1,9 +1,9 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var l=t[r]={i:r,l:!1,exports:{}};return e[r].call(l.exports,l,l.exports,n),l.l=!0,l.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)n.d(r,l,function(t){return e[t]}.bind(null,l));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t,n){"use strict";e.exports=n(4)},function(e,t,n){"use strict"; +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t,n){"use strict";e.exports=n(4)},function(e,t,n){"use strict"; /* object-assign (c) Sindre Sorhus @license MIT -*/var r=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,i,u=o(e),s=1;s
    @@ -89,13 +92,34 @@

    Type aliases

  • Type aliases

    +
    + +

    AutoVacuumOptions

    +
    AutoVacuumOptions: VacuumOptions & VacuumConditions
    + +
    +
    +

    Options to control auto vacuum behavior. When discarding a document with + MiniSearch.discard, a vacuuming operation is automatically started if the + dirtCount and dirtFactor are above the minDirtCount and minDirtFactor + thresholds defined by this configuration. See VacuumConditions for + details on these.

    +
    +

    Also, batchSize and batchWait can be specified, controlling batching + behavior (see VacuumOptions).

    +
    +

    MatchInfo

    MatchInfo: {}
    @@ -117,10 +141,10 @@
    [term:

    Options

    -
    Options<T>: { autoSuggestOptions?: SearchOptions; extractField?: undefined | ((document: T, fieldName: string) => string); fields: string[]; idField?: undefined | string; logger?: undefined | ((level: LogLevel, message: string, code?: undefined | string) => void); processTerm?: undefined | ((term: string, fieldName?: undefined | string) => string | string[] | null | undefined | false); searchOptions?: SearchOptions; storeFields?: string[]; tokenize?: undefined | ((text: string, fieldName?: undefined | string) => string[]) }
    +
    Options<T>: { autoSuggestOptions?: SearchOptions; autoVacuum?: boolean | AutoVacuumOptions; extractField?: undefined | ((document: T, fieldName: string) => string); fields: string[]; idField?: undefined | string; logger?: undefined | ((level: LogLevel, message: string, code?: undefined | string) => void); processTerm?: undefined | ((term: string, fieldName?: undefined | string) => string | string[] | null | undefined | false); searchOptions?: SearchOptions; storeFields?: string[]; tokenize?: undefined | ((text: string, fieldName?: undefined | string) => string[]) }
    @@ -151,6 +175,19 @@
    Optional autoSuggest
    +
  • +
    Optional autoVacuum?: boolean | AutoVacuumOptions
    +
    +
    +

    If true (the default), vacuuming is performed automatically as soon as + MiniSearch.discard is called a certain number of times, cleaning up + obsolete references from the index. If false, no automatic vacuuming is + performed. Custom settings controlling auto vacuuming thresholds, as well + as batching behavior, can be passed as an object (see the + AutoVacuumOptions type).

    +
    +
    +
  • Optional extractField?: undefined | ((document: T, fieldName: string) => string)
    @@ -236,7 +273,7 @@

    Query

    Query: QueryCombination | string
    @@ -252,7 +289,7 @@

    QueryCombination

    QueryCombination: SearchOptions & { queries: Query[] }
  • @@ -262,7 +299,7 @@

    SearchOptions

    SearchOptions: { boost?: undefined | {}; boostDocument?: undefined | ((documentId: any, term: string) => number); combineWith?: undefined | string; fields?: string[]; filter?: undefined | ((result: SearchResult) => boolean); fuzzy?: boolean | number | ((term: string, index: number, terms: string[]) => boolean | number); maxFuzzy?: undefined | number; prefix?: boolean | ((term: string, index: number, terms: string[]) => boolean); processTerm?: undefined | ((term: string) => string | string[] | null | undefined | false); tokenize?: undefined | ((text: string) => string[]); weights?: undefined | { fuzzy: number; prefix: number } }
    @@ -407,7 +444,7 @@

    SearchResult

    SearchResult: { id: any; match: MatchInfo; score: number; terms: string[] }
    @@ -469,7 +506,7 @@

    Suggestion

    Suggestion: { score: number; suggestion: string; terms: string[] }
    @@ -507,6 +544,89 @@
    terms: + +

    VacuumConditions

    +
    VacuumConditions: { minDirtCount?: undefined | number; minDirtFactor?: undefined | number }
    + +
    +
    +

    Sets minimum thresholds for dirtCount and dirtFactor that trigger an + automatic vacuuming.

    +
    +
    +
    +

    Type declaration

    +
      +
    • +
      Optional minDirtCount?: undefined | number
      +
      +
      +

      Minimum dirtCount (number of discarded documents since the last vacuuming) + under which auto vacuum is not triggered. It defaults to 20.

      +
      +
      +
    • +
    • +
      Optional minDirtFactor?: undefined | number
      +
      +
      +

      Minimum dirtFactor (proportion of discarded documents over the total) + under which auto vacuum is not triggered. It defaults to 0.1.

      +
      +
      +
    • +
    +
    +
    +
    + +

    VacuumOptions

    +
    VacuumOptions: { batchSize?: undefined | number; batchWait?: undefined | number }
    + +
    +
    +

    Options to control vacuuming behavior.

    +
    +

    Vacuuming cleans up document references made obsolete by + MiniSearch.discard from the index. On large indexes, vacuuming is + potentially costly, because it has to traverse the whole inverted index. + Therefore, in order to dilute this cost so it does not negatively affects the + application, vacuuming is performed in batches, with a delay between each + batch. These options are used to configure the batch size and the delay + between batches.

    +
    +
    +

    Type declaration

    +
      +
    • +
      Optional batchSize?: undefined | number
      +
      +
      +

      Size of each vacuuming batch (the number of terms in the index that will be + traversed in each batch). Defaults to 1000.

      +
      +
      +
    • +
    • +
      Optional batchWait?: undefined | number
      +
      +
      +

      Wait time between each vacuuming batch in milliseconds. Defaults to 10.

      +
      +
      +
    • +
    +
    +
    diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index ec5460de..79846497 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -190,11 +190,12 @@ export type Options = { logger?: (level: LogLevel, message: string, code?: string) => void /** - * If true (the default), vacuuming is performed automatically as soon as - * [[MiniSearch.discard]] is called a certain number of times, to clean up - * discarded documents from the index. If false, no auto-vacuuming is - * performed. Custom auto vacuuming settings can be passed as an object (see - * the [[AutoVacuumOptions]] type). + * If `true` (the default), vacuuming is performed automatically as soon as + * [[MiniSearch.discard]] is called a certain number of times, cleaning up + * obsolete references from the index. If `false`, no automatic vacuuming is + * performed. Custom settings controlling auto vacuuming thresholds, as well + * as batching behavior, can be passed as an object (see the + * [[AutoVacuumOptions]] type). */ autoVacuum?: boolean | AutoVacuumOptions @@ -319,17 +320,20 @@ export type QueryCombination = SearchOptions & { queries: Query[] } export type Query = QueryCombination | string /** - * Options to control vacuuming behavior. Vacuuming is only necessary when - * discarding documents with [[MiniSearch.discard]], and is a potentially costly - * operation on large indexes because it has to traverse the whole inverted - * index. Therefore, in order to avoid blocking the thread for long, it is - * performed in batches, with a delay between each batch. These options are used - * to configure the batch size and the delay between batches. + * Options to control vacuuming behavior. + * + * Vacuuming cleans up document references made obsolete by + * [[MiniSearch.discard]] from the index. On large indexes, vacuuming is + * potentially costly, because it has to traverse the whole inverted index. + * Therefore, in order to dilute this cost so it does not negatively affects the + * application, vacuuming is performed in batches, with a delay between each + * batch. These options are used to configure the batch size and the delay + * between batches. */ export type VacuumOptions = { /** - * Size of each vacuuming batch (the number of termsin the inverted index that - * will be traversed in each batch). Defaults to 1000. + * Size of each vacuuming batch (the number of terms in the index that will be + * traversed in each batch). Defaults to 1000. */ batchSize?: number, @@ -339,34 +343,42 @@ export type VacuumOptions = { batchWait?: number } +/** + * Sets minimum thresholds for `dirtCount` and `dirtFactor` that trigger an + * automatic vacuuming. + */ export type VacuumConditions = { /** - * Minimum dirt factor under which auto vacuum is not triggered. It defaults - * to 0.15. + * Minimum `dirtCount` (number of discarded documents since the last vacuuming) + * under which auto vacuum is not triggered. It defaults to 20. */ - minDirtFactor?: number, + minDirtCount?: number /** - * Minimum dirt count (number of discarded documents since the last vacuuming) - * under which auto vacuum is not triggered. It defaults to 20. + * Minimum `dirtFactor` (proportion of discarded documents over the total) + * under which auto vacuum is not triggered. It defaults to 0.1. */ - minDirtCount?: number + minDirtFactor?: number, } +/** + * Options to control auto vacuum behavior. When discarding a document with + * [[MiniSearch.discard]], a vacuuming operation is automatically started if the + * `dirtCount` and `dirtFactor` are above the `minDirtCount` and `minDirtFactor` + * thresholds defined by this configuration. See [[VacuumConditions]] for + * details on these. + * + * Also, `batchSize` and `batchWait` can be specified, controlling batching + * behavior (see [[VacuumOptions]]). + */ +export type AutoVacuumOptions = VacuumOptions & VacuumConditions + type QuerySpec = { prefix: boolean, fuzzy: number | boolean, term: string } -/** - * Options to control auto vacuum behavior. When discarding a document with - * [[MiniSearch.discard]], if vacuuming is not already in progress, and the - * dirtCount and dirtFactor are above the thresholds defined by this - * configuration, a vacuuming cycle is automatically started. - */ -export type AutoVacuumOptions = VacuumOptions & VacuumConditions - type DocumentTermFreqs = Map type FieldTermData = Map @@ -655,19 +667,14 @@ export default class MiniSearch { /** * Removes the given document from the index. * - * The document to delete must NOT have changed between indexing and deletion, - * otherwise the index will be corrupted. Therefore, when reindexing a document - * after a change, the correct order of operations is: - * - * 1. remove old version - * 2. apply changes - * 3. index new version + * The document to remove must NOT have changed between indexing and removal, + * otherwise the index will be corrupted. * - * This method is the cleanest way to remove a document, as it removes it from - * the inverted index. On the other hand, it requires having the full document - * to remove at hand. An alternative approach is [[MiniSearch.discard]], which - * only needs the ID of the document and has the same visible effect as - * remove, but does not immediately free up memory from the inverted index. + * This method requires passing the full document to be removed (not just the + * ID), and immediately removes the document from the inverted index, allowing + * memory to be released. A convenient alternative is [[MiniSearch.discard]], + * which needs only the document ID, and has the same visible effect, but + * delays cleaning up the index until the next vacuuming. * * @param document The document to be removed */ @@ -744,41 +751,42 @@ export default class MiniSearch { * Discards the document with the given ID, so it won't appear in search results * * It has the same visible effect of [[MiniSearch.remove]] (both cause the - * document to stop appearing in search results), but a different effect on - * the internal data structures: - * - * [[MiniSearch.remove]] takes the full document as argument, and removes it - * from the inverted index, releasing memory immediately. - * - * [[MiniSearch.discard]] instead only needs the document ID, and works by - * marking the current version of the document as discarded, scausing it to be - * ignored by search. The inverted index is not modified though, therefore - * memory is not released. - * - * The memory bloat resulting from repetite calls to [[MiniSearch.discard]] is - * cleaned up later by two mechanisms: clean up during search, and vacuuming. - * Upom search, whenever a discarded ID is found (and ignored for the - * results), references to the discarded document are removed from the - * inverted index entries for the search terms. This partially releases - * memory, but only for terms that have been searched at least once after - * discarding the document. - * - * Vacuuming is performed automatically (by default) after a certain number of - * documents are discarded, and traverses the inverted index cleaning up all - * references to discarded documents (see [[Options.autoVacuum]] and - * [[AutoVacuumOptions]]). Alternatively, manual vacuuming can be performed - * with [[MiniSearch.vacuum]]. - * - * In other words, [[MiniSearch.discard]] is faster and only takes an ID as - * argument, but it does not immediately release memory for the discarded - * document, and instead rely on delayed clean up and vacuuming. - * - * After discarding a document, it is possible to re-add a new version with - * that same ID, and the newly added version will appear in searches. In other - * words, discarding and re-adding a document has the same effect, as visible - * to the caller of MiniSearch, as removing and re-adding it. - * - * Alternatively, the [[MiniSearch.vacuum]] method can be called manually. + * document to stop appearing in searches), but a different effect on the + * internal data structures: + * + * - [[MiniSearch.remove]] requires passing the full document to be removed + * as argument, and removes it from the inverted index immediately. + * + * - [[MiniSearch.discard]] instead only needs the document ID, and works by + * marking the current version of the document as discarded, so it is + * immediately ignored by searches. This is faster and more convenient than + * `remove`, but the index is not immediately modified. To take care of + * that, vacuuming is performed after a certain number of documents are + * discarded, cleaning up the index and allowing memory to be released. + * + * After discarding a document, it is possible to re-add a new version, and + * only the new version will appear in searches. In other words, discarding + * and re-adding a document works exactly like removing and re-adding it. The + * [[MiniSearch.replace]] method can also be used to replace a document with a + * new version. + * + * #### Details about vacuuming + * + * Repetite calls to this method would leave obsolete document references in + * the index, invisible to searches. Two mechanisms take care of cleaning up: + * clean up during search, and vacuuming. + * + * - Upon search, whenever a discarded ID is found (and ignored for the + * results), references to the discarded document are removed from the + * inverted index entries for the search terms. This ensures that subsequent + * searches for the same terms do not need to skip these obsolete references + * again. + * + * - In addition, vacuuming is performed automatically by default (see the + * `autoVacuum` field in [[Options]]) after a certain number of documents + * are discarded. Vacuuming traverses all terms in the index, cleaning up + * all references to discarded documents. Vacuuming can also be triggered + * manually by calling [[MiniSearch.vacuum]]. * * @param id The ID of the document to be discarded */ @@ -813,13 +821,12 @@ export default class MiniSearch { * * It works by discarding the current version and adding the updated one, so * it is functionally equivalent to calling [[MiniSearch.discard]] followed by - * [[MiniSearch.add]]. The ID of the updated document should match the - * one to be replaced. + * [[MiniSearch.add]]. The ID of the updated document should be the same as + * the original one. * - * Since it relies on [[MiniSearch.discard]], this method does not immediately - * release memory for the replaced document, and instead relies on vacuuming - * to clean up eventually (see [[MiniSearch.discard]] and - * [[Options.autoVacuum]]). + * Since it uses [[MiniSearch.discard]] internally, this method relies on + * vacuuming to clean up obsolete document references from the index, allowing + * memory to be released (see [[MiniSearch.discard]]). * * @param updatedDocument The updated document to replace the old version * with @@ -833,22 +840,33 @@ export default class MiniSearch { } /** - * Triggers a manual vacuuming, that cleans up discarded documents from the - * inverted index + * Triggers a manual vacuuming, cleaning up references to discarded documents + * from the inverted index + * + * Vacuiuming is only useful for applications that use the + * [[MiniSearch.discard]] or [[MiniSearch.replace]] methods. * - * This function is only useful for applications that use the - * [[MiniSearch.discard]] method. Vacuuming traverses all terms in the - * inverted index in batches, and cleans up discarded documents from the - * posting list, releasing memory. While vacuuming is performed automatically - * by default (see [[AutoVacuumOptions]]), one can call this method to perfrom - * it manually. + * By default, vacuuming is performed automatically when needed (controlled by + * the `autoVacuum` field in [[Options]]), so there is usually no need to call + * this method, unless one wants to make sure to perform vacuuming at a + * specific moment. * - * The method takes an option argument with the following keys: + * Vacuuming traverses all terms in the inverted index in batches, and cleans + * up references to discarded documents from the posting list, allowing memory + * to be released. + * + * The method takes an optional object as argument with the following keys: * * - `batchSize`: the size of each batch (1000 by default) * - * - `batchWait`: the number of milliseconds to wait between batches, to - * avoid blocking the thread (10 by default) + * - `batchWait`: the number of milliseconds to wait between batches (10 by + * default) + * + * On large indexes, vacuuming could have a non-negligible cost: batching + * avoids blocking the thread for long, diluting this cost so that it is not + * negatively affecting the application. Nonetheless, this method should only + * be called when necessary, and relying on automatic vacuuming is usually + * better. * * It returns a promise that resolves (to undefined) when the clean up is * completed. If vacuuming is already ongoing at the time this method is @@ -857,11 +875,6 @@ export default class MiniSearch { * enqueued on top of the ongoing one, even if this method is called more * times (enqueuing multiple ones would be useless). * - * On large indexes, vacuuming can be expensive and take time to complete, - * hence the batching and wait to avoid blocking the thread for long. - * Therefore, this method should only be called when necessary, usually after - * several calls to [[MiniSearch.discard]], or before serializing the index. - * * @param options Configuration options for the batch size and delay. See * [[VacuumOptions]]. */ @@ -945,14 +958,14 @@ export default class MiniSearch { } /** - * Is true if a vacuuming operation is ongoing, false otherwise + * Is `true` if a vacuuming operation is ongoing, `false` otherwise */ get isVacuuming (): boolean { return this._currentVacuum != null } /** - * The number of documents discarded since the last vacuuming + * The number of documents discarded since the most recent vacuuming */ get dirtCount (): number { return this._dirtCount @@ -970,7 +983,8 @@ export default class MiniSearch { } /** - * Returns true if a document with the given ID was added to the index, false otherwise + * Returns `true` if a document with the given ID is present in the index and + * available for search, `false` otherwise * * @param id The document ID */ @@ -1230,7 +1244,7 @@ export default class MiniSearch { } /** - * Number of documents in the index + * Total number of documents available to search */ get documentCount (): number { return this._documentCount @@ -1795,7 +1809,7 @@ const defaultAutoSuggestOptions = { } const defaultVacuumOptions = { batchSize: 1000, batchWait: 10 } -const defaultVacuumConditions = { minDirtFactor: 0.15, minDirtCount: 20 } +const defaultVacuumConditions = { minDirtFactor: 0.1, minDirtCount: 20 } const defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions } From 7c80acbbe821af31941491bc138f669abd1ef30c Mon Sep 17 00:00:00 2001 From: Luca Ongaro Date: Wed, 23 Nov 2022 12:39:52 +0100 Subject: [PATCH 21/21] Add discardAll method --- docs/assets/js/search.json | 2 +- docs/classes/_minisearch_.minisearch.html | 79 +++++++++++++----- ...hablemap_searchablemap_.searchablemap.html | 36 ++++---- docs/examples/app.js | 6 +- docs/examples/billboard_1965-2015.json.gz | Bin 92024 -> 92024 bytes docs/modules/_minisearch_.html | 20 ++--- src/MiniSearch.test.js | 33 ++++++++ src/MiniSearch.ts | 32 +++++++ 8 files changed, 156 insertions(+), 52 deletions(-) diff --git a/docs/assets/js/search.json b/docs/assets/js/search.json index 6e5f1438..dda504ad 100644 --- a/docs/assets/js/search.json +++ b/docs/assets/js/search.json @@ -1 +1 @@ -{"kinds":{"1":"Module","32":"Variable","128":"Class","512":"Constructor","2048":"Method","65536":"Type literal","262144":"Accessor","4194304":"Type alias"},"rows":[{"id":0,"kind":1,"name":"\"SearchableMap/SearchableMap\"","url":"modules/_searchablemap_searchablemap_.html","classes":"tsd-kind-module"},{"id":1,"kind":128,"name":"SearchableMap","url":"classes/_searchablemap_searchablemap_.searchablemap.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"SearchableMap/SearchableMap\""},{"id":2,"kind":512,"name":"constructor","url":"classes/_searchablemap_searchablemap_.searchablemap.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":3,"kind":2048,"name":"atPrefix","url":"classes/_searchablemap_searchablemap_.searchablemap.html#atprefix","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":4,"kind":2048,"name":"clear","url":"classes/_searchablemap_searchablemap_.searchablemap.html#clear","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":5,"kind":2048,"name":"delete","url":"classes/_searchablemap_searchablemap_.searchablemap.html#delete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":6,"kind":2048,"name":"entries","url":"classes/_searchablemap_searchablemap_.searchablemap.html#entries","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":7,"kind":2048,"name":"forEach","url":"classes/_searchablemap_searchablemap_.searchablemap.html#foreach","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":8,"kind":2048,"name":"fuzzyGet","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fuzzyget","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":9,"kind":2048,"name":"get","url":"classes/_searchablemap_searchablemap_.searchablemap.html#get","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":10,"kind":2048,"name":"has","url":"classes/_searchablemap_searchablemap_.searchablemap.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":11,"kind":2048,"name":"keys","url":"classes/_searchablemap_searchablemap_.searchablemap.html#keys","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":12,"kind":2048,"name":"set","url":"classes/_searchablemap_searchablemap_.searchablemap.html#set","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":13,"kind":262144,"name":"size","url":"classes/_searchablemap_searchablemap_.searchablemap.html#size","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":14,"kind":2048,"name":"update","url":"classes/_searchablemap_searchablemap_.searchablemap.html#update","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":15,"kind":2048,"name":"fetch","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fetch","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":16,"kind":2048,"name":"values","url":"classes/_searchablemap_searchablemap_.searchablemap.html#values","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":17,"kind":2048,"name":"[Symbol.iterator]","url":"classes/_searchablemap_searchablemap_.searchablemap.html#_symbol_iterator_","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":18,"kind":2048,"name":"from","url":"classes/_searchablemap_searchablemap_.searchablemap.html#from","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":19,"kind":2048,"name":"fromObject","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fromobject","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":20,"kind":1,"name":"\"MiniSearch\"","url":"modules/_minisearch_.html","classes":"tsd-kind-module"},{"id":21,"kind":128,"name":"MiniSearch","url":"classes/_minisearch_.minisearch.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":22,"kind":512,"name":"constructor","url":"classes/_minisearch_.minisearch.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":23,"kind":2048,"name":"add","url":"classes/_minisearch_.minisearch.html#add","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":24,"kind":2048,"name":"addAll","url":"classes/_minisearch_.minisearch.html#addall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":25,"kind":2048,"name":"addAllAsync","url":"classes/_minisearch_.minisearch.html#addallasync","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":26,"kind":2048,"name":"remove","url":"classes/_minisearch_.minisearch.html#remove","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":27,"kind":2048,"name":"removeAll","url":"classes/_minisearch_.minisearch.html#removeall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":28,"kind":2048,"name":"discard","url":"classes/_minisearch_.minisearch.html#discard","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":29,"kind":2048,"name":"replace","url":"classes/_minisearch_.minisearch.html#replace","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":30,"kind":2048,"name":"vacuum","url":"classes/_minisearch_.minisearch.html#vacuum","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":31,"kind":262144,"name":"isVacuuming","url":"classes/_minisearch_.minisearch.html#isvacuuming","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":32,"kind":262144,"name":"dirtCount","url":"classes/_minisearch_.minisearch.html#dirtcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":33,"kind":262144,"name":"dirtFactor","url":"classes/_minisearch_.minisearch.html#dirtfactor","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":34,"kind":2048,"name":"has","url":"classes/_minisearch_.minisearch.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":35,"kind":2048,"name":"search","url":"classes/_minisearch_.minisearch.html#search","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":36,"kind":2048,"name":"autoSuggest","url":"classes/_minisearch_.minisearch.html#autosuggest","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":37,"kind":262144,"name":"documentCount","url":"classes/_minisearch_.minisearch.html#documentcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":38,"kind":262144,"name":"termCount","url":"classes/_minisearch_.minisearch.html#termcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":39,"kind":2048,"name":"loadJSON","url":"classes/_minisearch_.minisearch.html#loadjson","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":40,"kind":2048,"name":"getDefault","url":"classes/_minisearch_.minisearch.html#getdefault","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":41,"kind":2048,"name":"toJSON","url":"classes/_minisearch_.minisearch.html#tojson","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":42,"kind":4194304,"name":"SearchOptions","url":"modules/_minisearch_.html#searchoptions-1","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":43,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchoptions-1.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchOptions"},{"id":44,"kind":32,"name":"fields","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fields-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":45,"kind":32,"name":"filter","url":"modules/_minisearch_.html#searchoptions-1.__type-2.filter","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":46,"kind":32,"name":"boost","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boost","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":47,"kind":32,"name":"weights","url":"modules/_minisearch_.html#searchoptions-1.__type-2.weights","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":48,"kind":32,"name":"boostDocument","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boostdocument","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":49,"kind":32,"name":"prefix","url":"modules/_minisearch_.html#searchoptions-1.__type-2.prefix","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":50,"kind":32,"name":"fuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":51,"kind":32,"name":"maxFuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.maxfuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":52,"kind":32,"name":"combineWith","url":"modules/_minisearch_.html#searchoptions-1.__type-2.combinewith","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":53,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#searchoptions-1.__type-2.tokenize-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":54,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#searchoptions-1.__type-2.processterm-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":55,"kind":4194304,"name":"Options","url":"modules/_minisearch_.html#options","classes":"tsd-kind-type-alias tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":56,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#options.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Options"},{"id":57,"kind":32,"name":"fields","url":"modules/_minisearch_.html#options.__type-1.fields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":58,"kind":32,"name":"idField","url":"modules/_minisearch_.html#options.__type-1.idfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":59,"kind":32,"name":"storeFields","url":"modules/_minisearch_.html#options.__type-1.storefields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":60,"kind":32,"name":"extractField","url":"modules/_minisearch_.html#options.__type-1.extractfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":61,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#options.__type-1.tokenize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":62,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#options.__type-1.processterm","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":63,"kind":32,"name":"logger","url":"modules/_minisearch_.html#options.__type-1.logger","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":64,"kind":32,"name":"autoVacuum","url":"modules/_minisearch_.html#options.__type-1.autovacuum","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":65,"kind":32,"name":"searchOptions","url":"modules/_minisearch_.html#options.__type-1.searchoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":66,"kind":32,"name":"autoSuggestOptions","url":"modules/_minisearch_.html#options.__type-1.autosuggestoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":67,"kind":4194304,"name":"Suggestion","url":"modules/_minisearch_.html#suggestion","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":68,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#suggestion.__type-4","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Suggestion"},{"id":69,"kind":32,"name":"suggestion","url":"modules/_minisearch_.html#suggestion.__type-4.suggestion-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":70,"kind":32,"name":"terms","url":"modules/_minisearch_.html#suggestion.__type-4.terms-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":71,"kind":32,"name":"score","url":"modules/_minisearch_.html#suggestion.__type-4.score-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":72,"kind":4194304,"name":"MatchInfo","url":"modules/_minisearch_.html#matchinfo","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":73,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#matchinfo.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".MatchInfo"},{"id":74,"kind":4194304,"name":"SearchResult","url":"modules/_minisearch_.html#searchresult","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":75,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchresult.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchResult"},{"id":76,"kind":32,"name":"id","url":"modules/_minisearch_.html#searchresult.__type-3.id","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":77,"kind":32,"name":"terms","url":"modules/_minisearch_.html#searchresult.__type-3.terms","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":78,"kind":32,"name":"score","url":"modules/_minisearch_.html#searchresult.__type-3.score","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":79,"kind":32,"name":"match","url":"modules/_minisearch_.html#searchresult.__type-3.match","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":80,"kind":4194304,"name":"QueryCombination","url":"modules/_minisearch_.html#querycombination","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":81,"kind":4194304,"name":"Query","url":"modules/_minisearch_.html#query","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":82,"kind":4194304,"name":"VacuumOptions","url":"modules/_minisearch_.html#vacuumoptions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":83,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#vacuumoptions.__type-6","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".VacuumOptions"},{"id":84,"kind":32,"name":"batchSize","url":"modules/_minisearch_.html#vacuumoptions.__type-6.batchsize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumOptions.__type"},{"id":85,"kind":32,"name":"batchWait","url":"modules/_minisearch_.html#vacuumoptions.__type-6.batchwait","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumOptions.__type"},{"id":86,"kind":4194304,"name":"VacuumConditions","url":"modules/_minisearch_.html#vacuumconditions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":87,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#vacuumconditions.__type-5","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".VacuumConditions"},{"id":88,"kind":32,"name":"minDirtCount","url":"modules/_minisearch_.html#vacuumconditions.__type-5.mindirtcount","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumConditions.__type"},{"id":89,"kind":32,"name":"minDirtFactor","url":"modules/_minisearch_.html#vacuumconditions.__type-5.mindirtfactor","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumConditions.__type"},{"id":90,"kind":4194304,"name":"AutoVacuumOptions","url":"modules/_minisearch_.html#autovacuumoptions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,36.055]],["parent/0",[]],["name/1",[1,41.163]],["parent/1",[0,3.573]],["name/2",[2,36.055]],["parent/2",[3,1.589]],["name/3",[4,41.163]],["parent/3",[3,1.589]],["name/4",[5,41.163]],["parent/4",[3,1.589]],["name/5",[6,41.163]],["parent/5",[3,1.589]],["name/6",[7,41.163]],["parent/6",[3,1.589]],["name/7",[8,41.163]],["parent/7",[3,1.589]],["name/8",[9,41.163]],["parent/8",[3,1.589]],["name/9",[10,41.163]],["parent/9",[3,1.589]],["name/10",[11,36.055]],["parent/10",[3,1.589]],["name/11",[12,41.163]],["parent/11",[3,1.589]],["name/12",[13,41.163]],["parent/12",[3,1.589]],["name/13",[14,41.163]],["parent/13",[3,1.589]],["name/14",[15,41.163]],["parent/14",[3,1.589]],["name/15",[16,41.163]],["parent/15",[3,1.589]],["name/16",[17,41.163]],["parent/16",[3,1.589]],["name/17",[18,41.163]],["parent/17",[3,1.589]],["name/18",[19,41.163]],["parent/18",[3,1.589]],["name/19",[20,41.163]],["parent/19",[3,1.589]],["name/20",[21,19.191]],["parent/20",[]],["name/21",[21,19.191]],["parent/21",[21,1.902]],["name/22",[2,36.055]],["parent/22",[22,1.488]],["name/23",[23,41.163]],["parent/23",[22,1.488]],["name/24",[24,41.163]],["parent/24",[22,1.488]],["name/25",[25,41.163]],["parent/25",[22,1.488]],["name/26",[26,41.163]],["parent/26",[22,1.488]],["name/27",[27,41.163]],["parent/27",[22,1.488]],["name/28",[28,41.163]],["parent/28",[22,1.488]],["name/29",[29,41.163]],["parent/29",[22,1.488]],["name/30",[30,41.163]],["parent/30",[22,1.488]],["name/31",[31,41.163]],["parent/31",[22,1.488]],["name/32",[32,41.163]],["parent/32",[22,1.488]],["name/33",[33,41.163]],["parent/33",[22,1.488]],["name/34",[11,36.055]],["parent/34",[22,1.488]],["name/35",[34,41.163]],["parent/35",[22,1.488]],["name/36",[35,41.163]],["parent/36",[22,1.488]],["name/37",[36,41.163]],["parent/37",[22,1.488]],["name/38",[37,41.163]],["parent/38",[22,1.488]],["name/39",[38,41.163]],["parent/39",[22,1.488]],["name/40",[39,41.163]],["parent/40",[22,1.488]],["name/41",[40,41.163]],["parent/41",[22,1.488]],["name/42",[41,36.055]],["parent/42",[21,1.902]],["name/43",[42,25.069]],["parent/43",[43,4.079]],["name/44",[44,36.055]],["parent/44",[45,2.06]],["name/45",[46,41.163]],["parent/45",[45,2.06]],["name/46",[47,41.163]],["parent/46",[45,2.06]],["name/47",[48,41.163]],["parent/47",[45,2.06]],["name/48",[49,41.163]],["parent/48",[45,2.06]],["name/49",[50,41.163]],["parent/49",[45,2.06]],["name/50",[51,41.163]],["parent/50",[45,2.06]],["name/51",[52,41.163]],["parent/51",[45,2.06]],["name/52",[53,41.163]],["parent/52",[45,2.06]],["name/53",[54,36.055]],["parent/53",[45,2.06]],["name/54",[55,36.055]],["parent/54",[45,2.06]],["name/55",[56,41.163]],["parent/55",[21,1.902]],["name/56",[42,25.069]],["parent/56",[57,4.079]],["name/57",[44,36.055]],["parent/57",[58,2.151]],["name/58",[59,41.163]],["parent/58",[58,2.151]],["name/59",[60,41.163]],["parent/59",[58,2.151]],["name/60",[61,41.163]],["parent/60",[58,2.151]],["name/61",[54,36.055]],["parent/61",[58,2.151]],["name/62",[55,36.055]],["parent/62",[58,2.151]],["name/63",[62,41.163]],["parent/63",[58,2.151]],["name/64",[63,41.163]],["parent/64",[58,2.151]],["name/65",[41,36.055]],["parent/65",[58,2.151]],["name/66",[64,41.163]],["parent/66",[58,2.151]],["name/67",[65,36.055]],["parent/67",[21,1.902]],["name/68",[42,25.069]],["parent/68",[66,4.079]],["name/69",[65,36.055]],["parent/69",[67,3.239]],["name/70",[68,36.055]],["parent/70",[67,3.239]],["name/71",[69,36.055]],["parent/71",[67,3.239]],["name/72",[70,41.163]],["parent/72",[21,1.902]],["name/73",[42,25.069]],["parent/73",[71,4.079]],["name/74",[72,41.163]],["parent/74",[21,1.902]],["name/75",[42,25.069]],["parent/75",[73,4.079]],["name/76",[74,41.163]],["parent/76",[75,2.99]],["name/77",[68,36.055]],["parent/77",[75,2.99]],["name/78",[69,36.055]],["parent/78",[75,2.99]],["name/79",[76,41.163]],["parent/79",[75,2.99]],["name/80",[77,41.163]],["parent/80",[21,1.902]],["name/81",[78,41.163]],["parent/81",[21,1.902]],["name/82",[79,41.163]],["parent/82",[21,1.902]],["name/83",[42,25.069]],["parent/83",[80,4.079]],["name/84",[81,41.163]],["parent/84",[82,3.573]],["name/85",[83,41.163]],["parent/85",[82,3.573]],["name/86",[84,41.163]],["parent/86",[21,1.902]],["name/87",[42,25.069]],["parent/87",[85,4.079]],["name/88",[86,41.163]],["parent/88",[87,3.573]],["name/89",[88,41.163]],["parent/89",[87,3.573]],["name/90",[89,41.163]],["parent/90",[21,1.902]]],"invertedIndex":[["__type",{"_index":42,"name":{"43":{},"56":{},"68":{},"73":{},"75":{},"83":{},"87":{}},"parent":{}}],["add",{"_index":23,"name":{"23":{}},"parent":{}}],["addall",{"_index":24,"name":{"24":{}},"parent":{}}],["addallasync",{"_index":25,"name":{"25":{}},"parent":{}}],["atprefix",{"_index":4,"name":{"3":{}},"parent":{}}],["autosuggest",{"_index":35,"name":{"36":{}},"parent":{}}],["autosuggestoptions",{"_index":64,"name":{"66":{}},"parent":{}}],["autovacuum",{"_index":63,"name":{"64":{}},"parent":{}}],["autovacuumoptions",{"_index":89,"name":{"90":{}},"parent":{}}],["batchsize",{"_index":81,"name":{"84":{}},"parent":{}}],["batchwait",{"_index":83,"name":{"85":{}},"parent":{}}],["boost",{"_index":47,"name":{"46":{}},"parent":{}}],["boostdocument",{"_index":49,"name":{"48":{}},"parent":{}}],["clear",{"_index":5,"name":{"4":{}},"parent":{}}],["combinewith",{"_index":53,"name":{"52":{}},"parent":{}}],["constructor",{"_index":2,"name":{"2":{},"22":{}},"parent":{}}],["delete",{"_index":6,"name":{"5":{}},"parent":{}}],["dirtcount",{"_index":32,"name":{"32":{}},"parent":{}}],["dirtfactor",{"_index":33,"name":{"33":{}},"parent":{}}],["discard",{"_index":28,"name":{"28":{}},"parent":{}}],["documentcount",{"_index":36,"name":{"37":{}},"parent":{}}],["entries",{"_index":7,"name":{"6":{}},"parent":{}}],["extractfield",{"_index":61,"name":{"60":{}},"parent":{}}],["fetch",{"_index":16,"name":{"15":{}},"parent":{}}],["fields",{"_index":44,"name":{"44":{},"57":{}},"parent":{}}],["filter",{"_index":46,"name":{"45":{}},"parent":{}}],["foreach",{"_index":8,"name":{"7":{}},"parent":{}}],["from",{"_index":19,"name":{"18":{}},"parent":{}}],["fromobject",{"_index":20,"name":{"19":{}},"parent":{}}],["fuzzy",{"_index":51,"name":{"50":{}},"parent":{}}],["fuzzyget",{"_index":9,"name":{"8":{}},"parent":{}}],["get",{"_index":10,"name":{"9":{}},"parent":{}}],["getdefault",{"_index":39,"name":{"40":{}},"parent":{}}],["has",{"_index":11,"name":{"10":{},"34":{}},"parent":{}}],["id",{"_index":74,"name":{"76":{}},"parent":{}}],["idfield",{"_index":59,"name":{"58":{}},"parent":{}}],["isvacuuming",{"_index":31,"name":{"31":{}},"parent":{}}],["keys",{"_index":12,"name":{"11":{}},"parent":{}}],["loadjson",{"_index":38,"name":{"39":{}},"parent":{}}],["logger",{"_index":62,"name":{"63":{}},"parent":{}}],["match",{"_index":76,"name":{"79":{}},"parent":{}}],["matchinfo",{"_index":70,"name":{"72":{}},"parent":{}}],["maxfuzzy",{"_index":52,"name":{"51":{}},"parent":{}}],["mindirtcount",{"_index":86,"name":{"88":{}},"parent":{}}],["mindirtfactor",{"_index":88,"name":{"89":{}},"parent":{}}],["minisearch",{"_index":21,"name":{"20":{},"21":{}},"parent":{"21":{},"42":{},"55":{},"67":{},"72":{},"74":{},"80":{},"81":{},"82":{},"86":{},"90":{}}}],["minisearch\".matchinfo",{"_index":71,"name":{},"parent":{"73":{}}}],["minisearch\".minisearch",{"_index":22,"name":{},"parent":{"22":{},"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"31":{},"32":{},"33":{},"34":{},"35":{},"36":{},"37":{},"38":{},"39":{},"40":{},"41":{}}}],["minisearch\".options",{"_index":57,"name":{},"parent":{"56":{}}}],["minisearch\".options.__type",{"_index":58,"name":{},"parent":{"57":{},"58":{},"59":{},"60":{},"61":{},"62":{},"63":{},"64":{},"65":{},"66":{}}}],["minisearch\".searchoptions",{"_index":43,"name":{},"parent":{"43":{}}}],["minisearch\".searchoptions.__type",{"_index":45,"name":{},"parent":{"44":{},"45":{},"46":{},"47":{},"48":{},"49":{},"50":{},"51":{},"52":{},"53":{},"54":{}}}],["minisearch\".searchresult",{"_index":73,"name":{},"parent":{"75":{}}}],["minisearch\".searchresult.__type",{"_index":75,"name":{},"parent":{"76":{},"77":{},"78":{},"79":{}}}],["minisearch\".suggestion",{"_index":66,"name":{},"parent":{"68":{}}}],["minisearch\".suggestion.__type",{"_index":67,"name":{},"parent":{"69":{},"70":{},"71":{}}}],["minisearch\".vacuumconditions",{"_index":85,"name":{},"parent":{"87":{}}}],["minisearch\".vacuumconditions.__type",{"_index":87,"name":{},"parent":{"88":{},"89":{}}}],["minisearch\".vacuumoptions",{"_index":80,"name":{},"parent":{"83":{}}}],["minisearch\".vacuumoptions.__type",{"_index":82,"name":{},"parent":{"84":{},"85":{}}}],["options",{"_index":56,"name":{"55":{}},"parent":{}}],["prefix",{"_index":50,"name":{"49":{}},"parent":{}}],["processterm",{"_index":55,"name":{"54":{},"62":{}},"parent":{}}],["query",{"_index":78,"name":{"81":{}},"parent":{}}],["querycombination",{"_index":77,"name":{"80":{}},"parent":{}}],["remove",{"_index":26,"name":{"26":{}},"parent":{}}],["removeall",{"_index":27,"name":{"27":{}},"parent":{}}],["replace",{"_index":29,"name":{"29":{}},"parent":{}}],["score",{"_index":69,"name":{"71":{},"78":{}},"parent":{}}],["search",{"_index":34,"name":{"35":{}},"parent":{}}],["searchablemap",{"_index":1,"name":{"1":{}},"parent":{}}],["searchablemap/searchablemap",{"_index":0,"name":{"0":{}},"parent":{"1":{}}}],["searchablemap/searchablemap\".searchablemap",{"_index":3,"name":{},"parent":{"2":{},"3":{},"4":{},"5":{},"6":{},"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{}}}],["searchoptions",{"_index":41,"name":{"42":{},"65":{}},"parent":{}}],["searchresult",{"_index":72,"name":{"74":{}},"parent":{}}],["set",{"_index":13,"name":{"12":{}},"parent":{}}],["size",{"_index":14,"name":{"13":{}},"parent":{}}],["storefields",{"_index":60,"name":{"59":{}},"parent":{}}],["suggestion",{"_index":65,"name":{"67":{},"69":{}},"parent":{}}],["symbol.iterator",{"_index":18,"name":{"17":{}},"parent":{}}],["termcount",{"_index":37,"name":{"38":{}},"parent":{}}],["terms",{"_index":68,"name":{"70":{},"77":{}},"parent":{}}],["tojson",{"_index":40,"name":{"41":{}},"parent":{}}],["tokenize",{"_index":54,"name":{"53":{},"61":{}},"parent":{}}],["update",{"_index":15,"name":{"14":{}},"parent":{}}],["vacuum",{"_index":30,"name":{"30":{}},"parent":{}}],["vacuumconditions",{"_index":84,"name":{"86":{}},"parent":{}}],["vacuumoptions",{"_index":79,"name":{"82":{}},"parent":{}}],["values",{"_index":17,"name":{"16":{}},"parent":{}}],["weights",{"_index":48,"name":{"47":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file +{"kinds":{"1":"Module","32":"Variable","128":"Class","512":"Constructor","2048":"Method","65536":"Type literal","262144":"Accessor","4194304":"Type alias"},"rows":[{"id":0,"kind":1,"name":"\"SearchableMap/SearchableMap\"","url":"modules/_searchablemap_searchablemap_.html","classes":"tsd-kind-module"},{"id":1,"kind":128,"name":"SearchableMap","url":"classes/_searchablemap_searchablemap_.searchablemap.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"SearchableMap/SearchableMap\""},{"id":2,"kind":512,"name":"constructor","url":"classes/_searchablemap_searchablemap_.searchablemap.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":3,"kind":2048,"name":"atPrefix","url":"classes/_searchablemap_searchablemap_.searchablemap.html#atprefix","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":4,"kind":2048,"name":"clear","url":"classes/_searchablemap_searchablemap_.searchablemap.html#clear","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":5,"kind":2048,"name":"delete","url":"classes/_searchablemap_searchablemap_.searchablemap.html#delete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":6,"kind":2048,"name":"entries","url":"classes/_searchablemap_searchablemap_.searchablemap.html#entries","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":7,"kind":2048,"name":"forEach","url":"classes/_searchablemap_searchablemap_.searchablemap.html#foreach","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":8,"kind":2048,"name":"fuzzyGet","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fuzzyget","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":9,"kind":2048,"name":"get","url":"classes/_searchablemap_searchablemap_.searchablemap.html#get","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":10,"kind":2048,"name":"has","url":"classes/_searchablemap_searchablemap_.searchablemap.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":11,"kind":2048,"name":"keys","url":"classes/_searchablemap_searchablemap_.searchablemap.html#keys","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":12,"kind":2048,"name":"set","url":"classes/_searchablemap_searchablemap_.searchablemap.html#set","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":13,"kind":262144,"name":"size","url":"classes/_searchablemap_searchablemap_.searchablemap.html#size","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":14,"kind":2048,"name":"update","url":"classes/_searchablemap_searchablemap_.searchablemap.html#update","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":15,"kind":2048,"name":"fetch","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fetch","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":16,"kind":2048,"name":"values","url":"classes/_searchablemap_searchablemap_.searchablemap.html#values","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":17,"kind":2048,"name":"[Symbol.iterator]","url":"classes/_searchablemap_searchablemap_.searchablemap.html#_symbol_iterator_","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":18,"kind":2048,"name":"from","url":"classes/_searchablemap_searchablemap_.searchablemap.html#from","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":19,"kind":2048,"name":"fromObject","url":"classes/_searchablemap_searchablemap_.searchablemap.html#fromobject","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"SearchableMap/SearchableMap\".SearchableMap"},{"id":20,"kind":1,"name":"\"MiniSearch\"","url":"modules/_minisearch_.html","classes":"tsd-kind-module"},{"id":21,"kind":128,"name":"MiniSearch","url":"classes/_minisearch_.minisearch.html","classes":"tsd-kind-class tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":22,"kind":512,"name":"constructor","url":"classes/_minisearch_.minisearch.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":23,"kind":2048,"name":"add","url":"classes/_minisearch_.minisearch.html#add","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":24,"kind":2048,"name":"addAll","url":"classes/_minisearch_.minisearch.html#addall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":25,"kind":2048,"name":"addAllAsync","url":"classes/_minisearch_.minisearch.html#addallasync","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":26,"kind":2048,"name":"remove","url":"classes/_minisearch_.minisearch.html#remove","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":27,"kind":2048,"name":"removeAll","url":"classes/_minisearch_.minisearch.html#removeall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":28,"kind":2048,"name":"discard","url":"classes/_minisearch_.minisearch.html#discard","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":29,"kind":2048,"name":"discardAll","url":"classes/_minisearch_.minisearch.html#discardall","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":30,"kind":2048,"name":"replace","url":"classes/_minisearch_.minisearch.html#replace","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":31,"kind":2048,"name":"vacuum","url":"classes/_minisearch_.minisearch.html#vacuum","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":32,"kind":262144,"name":"isVacuuming","url":"classes/_minisearch_.minisearch.html#isvacuuming","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":33,"kind":262144,"name":"dirtCount","url":"classes/_minisearch_.minisearch.html#dirtcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":34,"kind":262144,"name":"dirtFactor","url":"classes/_minisearch_.minisearch.html#dirtfactor","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":35,"kind":2048,"name":"has","url":"classes/_minisearch_.minisearch.html#has","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":36,"kind":2048,"name":"search","url":"classes/_minisearch_.minisearch.html#search","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":37,"kind":2048,"name":"autoSuggest","url":"classes/_minisearch_.minisearch.html#autosuggest","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":38,"kind":262144,"name":"documentCount","url":"classes/_minisearch_.minisearch.html#documentcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":39,"kind":262144,"name":"termCount","url":"classes/_minisearch_.minisearch.html#termcount","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":40,"kind":2048,"name":"loadJSON","url":"classes/_minisearch_.minisearch.html#loadjson","classes":"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":41,"kind":2048,"name":"getDefault","url":"classes/_minisearch_.minisearch.html#getdefault","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"\"MiniSearch\".MiniSearch"},{"id":42,"kind":2048,"name":"toJSON","url":"classes/_minisearch_.minisearch.html#tojson","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MiniSearch\".MiniSearch"},{"id":43,"kind":4194304,"name":"SearchOptions","url":"modules/_minisearch_.html#searchoptions-1","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":44,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchoptions-1.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchOptions"},{"id":45,"kind":32,"name":"fields","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fields-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":46,"kind":32,"name":"filter","url":"modules/_minisearch_.html#searchoptions-1.__type-2.filter","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":47,"kind":32,"name":"boost","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boost","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":48,"kind":32,"name":"weights","url":"modules/_minisearch_.html#searchoptions-1.__type-2.weights","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":49,"kind":32,"name":"boostDocument","url":"modules/_minisearch_.html#searchoptions-1.__type-2.boostdocument","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":50,"kind":32,"name":"prefix","url":"modules/_minisearch_.html#searchoptions-1.__type-2.prefix","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":51,"kind":32,"name":"fuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.fuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":52,"kind":32,"name":"maxFuzzy","url":"modules/_minisearch_.html#searchoptions-1.__type-2.maxfuzzy","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":53,"kind":32,"name":"combineWith","url":"modules/_minisearch_.html#searchoptions-1.__type-2.combinewith","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":54,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#searchoptions-1.__type-2.tokenize-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":55,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#searchoptions-1.__type-2.processterm-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchOptions.__type"},{"id":56,"kind":4194304,"name":"Options","url":"modules/_minisearch_.html#options","classes":"tsd-kind-type-alias tsd-parent-kind-module tsd-has-type-parameter","parent":"\"MiniSearch\""},{"id":57,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#options.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Options"},{"id":58,"kind":32,"name":"fields","url":"modules/_minisearch_.html#options.__type-1.fields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":59,"kind":32,"name":"idField","url":"modules/_minisearch_.html#options.__type-1.idfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":60,"kind":32,"name":"storeFields","url":"modules/_minisearch_.html#options.__type-1.storefields","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":61,"kind":32,"name":"extractField","url":"modules/_minisearch_.html#options.__type-1.extractfield","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":62,"kind":32,"name":"tokenize","url":"modules/_minisearch_.html#options.__type-1.tokenize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":63,"kind":32,"name":"processTerm","url":"modules/_minisearch_.html#options.__type-1.processterm","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":64,"kind":32,"name":"logger","url":"modules/_minisearch_.html#options.__type-1.logger","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":65,"kind":32,"name":"autoVacuum","url":"modules/_minisearch_.html#options.__type-1.autovacuum","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":66,"kind":32,"name":"searchOptions","url":"modules/_minisearch_.html#options.__type-1.searchoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":67,"kind":32,"name":"autoSuggestOptions","url":"modules/_minisearch_.html#options.__type-1.autosuggestoptions","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Options.__type"},{"id":68,"kind":4194304,"name":"Suggestion","url":"modules/_minisearch_.html#suggestion","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":69,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#suggestion.__type-4","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".Suggestion"},{"id":70,"kind":32,"name":"suggestion","url":"modules/_minisearch_.html#suggestion.__type-4.suggestion-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":71,"kind":32,"name":"terms","url":"modules/_minisearch_.html#suggestion.__type-4.terms-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":72,"kind":32,"name":"score","url":"modules/_minisearch_.html#suggestion.__type-4.score-1","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".Suggestion.__type"},{"id":73,"kind":4194304,"name":"MatchInfo","url":"modules/_minisearch_.html#matchinfo","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":74,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#matchinfo.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".MatchInfo"},{"id":75,"kind":4194304,"name":"SearchResult","url":"modules/_minisearch_.html#searchresult","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":76,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#searchresult.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".SearchResult"},{"id":77,"kind":32,"name":"id","url":"modules/_minisearch_.html#searchresult.__type-3.id","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":78,"kind":32,"name":"terms","url":"modules/_minisearch_.html#searchresult.__type-3.terms","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":79,"kind":32,"name":"score","url":"modules/_minisearch_.html#searchresult.__type-3.score","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":80,"kind":32,"name":"match","url":"modules/_minisearch_.html#searchresult.__type-3.match","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".SearchResult.__type"},{"id":81,"kind":4194304,"name":"QueryCombination","url":"modules/_minisearch_.html#querycombination","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":82,"kind":4194304,"name":"Query","url":"modules/_minisearch_.html#query","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":83,"kind":4194304,"name":"VacuumOptions","url":"modules/_minisearch_.html#vacuumoptions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":84,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#vacuumoptions.__type-6","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".VacuumOptions"},{"id":85,"kind":32,"name":"batchSize","url":"modules/_minisearch_.html#vacuumoptions.__type-6.batchsize","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumOptions.__type"},{"id":86,"kind":32,"name":"batchWait","url":"modules/_minisearch_.html#vacuumoptions.__type-6.batchwait","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumOptions.__type"},{"id":87,"kind":4194304,"name":"VacuumConditions","url":"modules/_minisearch_.html#vacuumconditions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""},{"id":88,"kind":65536,"name":"__type","url":"modules/_minisearch_.html#vacuumconditions.__type-5","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"\"MiniSearch\".VacuumConditions"},{"id":89,"kind":32,"name":"minDirtCount","url":"modules/_minisearch_.html#vacuumconditions.__type-5.mindirtcount","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumConditions.__type"},{"id":90,"kind":32,"name":"minDirtFactor","url":"modules/_minisearch_.html#vacuumconditions.__type-5.mindirtfactor","classes":"tsd-kind-variable tsd-parent-kind-type-literal","parent":"\"MiniSearch\".VacuumConditions.__type"},{"id":91,"kind":4194304,"name":"AutoVacuumOptions","url":"modules/_minisearch_.html#autovacuumoptions","classes":"tsd-kind-type-alias tsd-parent-kind-module","parent":"\"MiniSearch\""}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,36.163]],["parent/0",[]],["name/1",[1,41.271]],["parent/1",[0,3.584]],["name/2",[2,36.163]],["parent/2",[3,1.6]],["name/3",[4,41.271]],["parent/3",[3,1.6]],["name/4",[5,41.271]],["parent/4",[3,1.6]],["name/5",[6,41.271]],["parent/5",[3,1.6]],["name/6",[7,41.271]],["parent/6",[3,1.6]],["name/7",[8,41.271]],["parent/7",[3,1.6]],["name/8",[9,41.271]],["parent/8",[3,1.6]],["name/9",[10,41.271]],["parent/9",[3,1.6]],["name/10",[11,36.163]],["parent/10",[3,1.6]],["name/11",[12,41.271]],["parent/11",[3,1.6]],["name/12",[13,41.271]],["parent/12",[3,1.6]],["name/13",[14,41.271]],["parent/13",[3,1.6]],["name/14",[15,41.271]],["parent/14",[3,1.6]],["name/15",[16,41.271]],["parent/15",[3,1.6]],["name/16",[17,41.271]],["parent/16",[3,1.6]],["name/17",[18,41.271]],["parent/17",[3,1.6]],["name/18",[19,41.271]],["parent/18",[3,1.6]],["name/19",[20,41.271]],["parent/19",[3,1.6]],["name/20",[21,19.299]],["parent/20",[]],["name/21",[21,19.299]],["parent/21",[21,1.913]],["name/22",[2,36.163]],["parent/22",[22,1.451]],["name/23",[23,41.271]],["parent/23",[22,1.451]],["name/24",[24,41.271]],["parent/24",[22,1.451]],["name/25",[25,41.271]],["parent/25",[22,1.451]],["name/26",[26,41.271]],["parent/26",[22,1.451]],["name/27",[27,41.271]],["parent/27",[22,1.451]],["name/28",[28,41.271]],["parent/28",[22,1.451]],["name/29",[29,41.271]],["parent/29",[22,1.451]],["name/30",[30,41.271]],["parent/30",[22,1.451]],["name/31",[31,41.271]],["parent/31",[22,1.451]],["name/32",[32,41.271]],["parent/32",[22,1.451]],["name/33",[33,41.271]],["parent/33",[22,1.451]],["name/34",[34,41.271]],["parent/34",[22,1.451]],["name/35",[11,36.163]],["parent/35",[22,1.451]],["name/36",[35,41.271]],["parent/36",[22,1.451]],["name/37",[36,41.271]],["parent/37",[22,1.451]],["name/38",[37,41.271]],["parent/38",[22,1.451]],["name/39",[38,41.271]],["parent/39",[22,1.451]],["name/40",[39,41.271]],["parent/40",[22,1.451]],["name/41",[40,41.271]],["parent/41",[22,1.451]],["name/42",[41,41.271]],["parent/42",[22,1.451]],["name/43",[42,36.163]],["parent/43",[21,1.913]],["name/44",[43,25.177]],["parent/44",[44,4.09]],["name/45",[45,36.163]],["parent/45",[46,2.071]],["name/46",[47,41.271]],["parent/46",[46,2.071]],["name/47",[48,41.271]],["parent/47",[46,2.071]],["name/48",[49,41.271]],["parent/48",[46,2.071]],["name/49",[50,41.271]],["parent/49",[46,2.071]],["name/50",[51,41.271]],["parent/50",[46,2.071]],["name/51",[52,41.271]],["parent/51",[46,2.071]],["name/52",[53,41.271]],["parent/52",[46,2.071]],["name/53",[54,41.271]],["parent/53",[46,2.071]],["name/54",[55,36.163]],["parent/54",[46,2.071]],["name/55",[56,36.163]],["parent/55",[46,2.071]],["name/56",[57,41.271]],["parent/56",[21,1.913]],["name/57",[43,25.177]],["parent/57",[58,4.09]],["name/58",[45,36.163]],["parent/58",[59,2.162]],["name/59",[60,41.271]],["parent/59",[59,2.162]],["name/60",[61,41.271]],["parent/60",[59,2.162]],["name/61",[62,41.271]],["parent/61",[59,2.162]],["name/62",[55,36.163]],["parent/62",[59,2.162]],["name/63",[56,36.163]],["parent/63",[59,2.162]],["name/64",[63,41.271]],["parent/64",[59,2.162]],["name/65",[64,41.271]],["parent/65",[59,2.162]],["name/66",[42,36.163]],["parent/66",[59,2.162]],["name/67",[65,41.271]],["parent/67",[59,2.162]],["name/68",[66,36.163]],["parent/68",[21,1.913]],["name/69",[43,25.177]],["parent/69",[67,4.09]],["name/70",[66,36.163]],["parent/70",[68,3.25]],["name/71",[69,36.163]],["parent/71",[68,3.25]],["name/72",[70,36.163]],["parent/72",[68,3.25]],["name/73",[71,41.271]],["parent/73",[21,1.913]],["name/74",[43,25.177]],["parent/74",[72,4.09]],["name/75",[73,41.271]],["parent/75",[21,1.913]],["name/76",[43,25.177]],["parent/76",[74,4.09]],["name/77",[75,41.271]],["parent/77",[76,3.001]],["name/78",[69,36.163]],["parent/78",[76,3.001]],["name/79",[70,36.163]],["parent/79",[76,3.001]],["name/80",[77,41.271]],["parent/80",[76,3.001]],["name/81",[78,41.271]],["parent/81",[21,1.913]],["name/82",[79,41.271]],["parent/82",[21,1.913]],["name/83",[80,41.271]],["parent/83",[21,1.913]],["name/84",[43,25.177]],["parent/84",[81,4.09]],["name/85",[82,41.271]],["parent/85",[83,3.584]],["name/86",[84,41.271]],["parent/86",[83,3.584]],["name/87",[85,41.271]],["parent/87",[21,1.913]],["name/88",[43,25.177]],["parent/88",[86,4.09]],["name/89",[87,41.271]],["parent/89",[88,3.584]],["name/90",[89,41.271]],["parent/90",[88,3.584]],["name/91",[90,41.271]],["parent/91",[21,1.913]]],"invertedIndex":[["__type",{"_index":43,"name":{"44":{},"57":{},"69":{},"74":{},"76":{},"84":{},"88":{}},"parent":{}}],["add",{"_index":23,"name":{"23":{}},"parent":{}}],["addall",{"_index":24,"name":{"24":{}},"parent":{}}],["addallasync",{"_index":25,"name":{"25":{}},"parent":{}}],["atprefix",{"_index":4,"name":{"3":{}},"parent":{}}],["autosuggest",{"_index":36,"name":{"37":{}},"parent":{}}],["autosuggestoptions",{"_index":65,"name":{"67":{}},"parent":{}}],["autovacuum",{"_index":64,"name":{"65":{}},"parent":{}}],["autovacuumoptions",{"_index":90,"name":{"91":{}},"parent":{}}],["batchsize",{"_index":82,"name":{"85":{}},"parent":{}}],["batchwait",{"_index":84,"name":{"86":{}},"parent":{}}],["boost",{"_index":48,"name":{"47":{}},"parent":{}}],["boostdocument",{"_index":50,"name":{"49":{}},"parent":{}}],["clear",{"_index":5,"name":{"4":{}},"parent":{}}],["combinewith",{"_index":54,"name":{"53":{}},"parent":{}}],["constructor",{"_index":2,"name":{"2":{},"22":{}},"parent":{}}],["delete",{"_index":6,"name":{"5":{}},"parent":{}}],["dirtcount",{"_index":33,"name":{"33":{}},"parent":{}}],["dirtfactor",{"_index":34,"name":{"34":{}},"parent":{}}],["discard",{"_index":28,"name":{"28":{}},"parent":{}}],["discardall",{"_index":29,"name":{"29":{}},"parent":{}}],["documentcount",{"_index":37,"name":{"38":{}},"parent":{}}],["entries",{"_index":7,"name":{"6":{}},"parent":{}}],["extractfield",{"_index":62,"name":{"61":{}},"parent":{}}],["fetch",{"_index":16,"name":{"15":{}},"parent":{}}],["fields",{"_index":45,"name":{"45":{},"58":{}},"parent":{}}],["filter",{"_index":47,"name":{"46":{}},"parent":{}}],["foreach",{"_index":8,"name":{"7":{}},"parent":{}}],["from",{"_index":19,"name":{"18":{}},"parent":{}}],["fromobject",{"_index":20,"name":{"19":{}},"parent":{}}],["fuzzy",{"_index":52,"name":{"51":{}},"parent":{}}],["fuzzyget",{"_index":9,"name":{"8":{}},"parent":{}}],["get",{"_index":10,"name":{"9":{}},"parent":{}}],["getdefault",{"_index":40,"name":{"41":{}},"parent":{}}],["has",{"_index":11,"name":{"10":{},"35":{}},"parent":{}}],["id",{"_index":75,"name":{"77":{}},"parent":{}}],["idfield",{"_index":60,"name":{"59":{}},"parent":{}}],["isvacuuming",{"_index":32,"name":{"32":{}},"parent":{}}],["keys",{"_index":12,"name":{"11":{}},"parent":{}}],["loadjson",{"_index":39,"name":{"40":{}},"parent":{}}],["logger",{"_index":63,"name":{"64":{}},"parent":{}}],["match",{"_index":77,"name":{"80":{}},"parent":{}}],["matchinfo",{"_index":71,"name":{"73":{}},"parent":{}}],["maxfuzzy",{"_index":53,"name":{"52":{}},"parent":{}}],["mindirtcount",{"_index":87,"name":{"89":{}},"parent":{}}],["mindirtfactor",{"_index":89,"name":{"90":{}},"parent":{}}],["minisearch",{"_index":21,"name":{"20":{},"21":{}},"parent":{"21":{},"43":{},"56":{},"68":{},"73":{},"75":{},"81":{},"82":{},"83":{},"87":{},"91":{}}}],["minisearch\".matchinfo",{"_index":72,"name":{},"parent":{"74":{}}}],["minisearch\".minisearch",{"_index":22,"name":{},"parent":{"22":{},"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"31":{},"32":{},"33":{},"34":{},"35":{},"36":{},"37":{},"38":{},"39":{},"40":{},"41":{},"42":{}}}],["minisearch\".options",{"_index":58,"name":{},"parent":{"57":{}}}],["minisearch\".options.__type",{"_index":59,"name":{},"parent":{"58":{},"59":{},"60":{},"61":{},"62":{},"63":{},"64":{},"65":{},"66":{},"67":{}}}],["minisearch\".searchoptions",{"_index":44,"name":{},"parent":{"44":{}}}],["minisearch\".searchoptions.__type",{"_index":46,"name":{},"parent":{"45":{},"46":{},"47":{},"48":{},"49":{},"50":{},"51":{},"52":{},"53":{},"54":{},"55":{}}}],["minisearch\".searchresult",{"_index":74,"name":{},"parent":{"76":{}}}],["minisearch\".searchresult.__type",{"_index":76,"name":{},"parent":{"77":{},"78":{},"79":{},"80":{}}}],["minisearch\".suggestion",{"_index":67,"name":{},"parent":{"69":{}}}],["minisearch\".suggestion.__type",{"_index":68,"name":{},"parent":{"70":{},"71":{},"72":{}}}],["minisearch\".vacuumconditions",{"_index":86,"name":{},"parent":{"88":{}}}],["minisearch\".vacuumconditions.__type",{"_index":88,"name":{},"parent":{"89":{},"90":{}}}],["minisearch\".vacuumoptions",{"_index":81,"name":{},"parent":{"84":{}}}],["minisearch\".vacuumoptions.__type",{"_index":83,"name":{},"parent":{"85":{},"86":{}}}],["options",{"_index":57,"name":{"56":{}},"parent":{}}],["prefix",{"_index":51,"name":{"50":{}},"parent":{}}],["processterm",{"_index":56,"name":{"55":{},"63":{}},"parent":{}}],["query",{"_index":79,"name":{"82":{}},"parent":{}}],["querycombination",{"_index":78,"name":{"81":{}},"parent":{}}],["remove",{"_index":26,"name":{"26":{}},"parent":{}}],["removeall",{"_index":27,"name":{"27":{}},"parent":{}}],["replace",{"_index":30,"name":{"30":{}},"parent":{}}],["score",{"_index":70,"name":{"72":{},"79":{}},"parent":{}}],["search",{"_index":35,"name":{"36":{}},"parent":{}}],["searchablemap",{"_index":1,"name":{"1":{}},"parent":{}}],["searchablemap/searchablemap",{"_index":0,"name":{"0":{}},"parent":{"1":{}}}],["searchablemap/searchablemap\".searchablemap",{"_index":3,"name":{},"parent":{"2":{},"3":{},"4":{},"5":{},"6":{},"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{}}}],["searchoptions",{"_index":42,"name":{"43":{},"66":{}},"parent":{}}],["searchresult",{"_index":73,"name":{"75":{}},"parent":{}}],["set",{"_index":13,"name":{"12":{}},"parent":{}}],["size",{"_index":14,"name":{"13":{}},"parent":{}}],["storefields",{"_index":61,"name":{"60":{}},"parent":{}}],["suggestion",{"_index":66,"name":{"68":{},"70":{}},"parent":{}}],["symbol.iterator",{"_index":18,"name":{"17":{}},"parent":{}}],["termcount",{"_index":38,"name":{"39":{}},"parent":{}}],["terms",{"_index":69,"name":{"71":{},"78":{}},"parent":{}}],["tojson",{"_index":41,"name":{"42":{}},"parent":{}}],["tokenize",{"_index":55,"name":{"54":{},"62":{}},"parent":{}}],["update",{"_index":15,"name":{"14":{}},"parent":{}}],["vacuum",{"_index":31,"name":{"31":{}},"parent":{}}],["vacuumconditions",{"_index":85,"name":{"87":{}},"parent":{}}],["vacuumoptions",{"_index":80,"name":{"83":{}},"parent":{}}],["values",{"_index":17,"name":{"16":{}},"parent":{}}],["weights",{"_index":49,"name":{"48":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/docs/classes/_minisearch_.minisearch.html b/docs/classes/_minisearch_.minisearch.html index 974f0c64..58485d9f 100644 --- a/docs/classes/_minisearch_.minisearch.html +++ b/docs/classes/_minisearch_.minisearch.html @@ -171,6 +171,7 @@

    Methods

  • addAllAsync
  • autoSuggest
  • discard
  • +
  • discardAll
  • has
  • remove
  • removeAll
  • @@ -197,7 +198,7 @@

    constructor

  • @@ -285,7 +286,7 @@

    dirtCount

  • @@ -307,7 +308,7 @@

    dirtFactor

  • @@ -333,7 +334,7 @@

    documentCount

  • @@ -355,7 +356,7 @@

    isVacuuming

  • @@ -377,7 +378,7 @@

    termCount

  • @@ -402,7 +403,7 @@

    add

  • @@ -433,7 +434,7 @@

    addAll

  • @@ -464,7 +465,7 @@

    addAllAsync

  • @@ -510,7 +511,7 @@

    autoSuggest

  • @@ -596,7 +597,7 @@

    discard

  • @@ -657,6 +658,41 @@

    Returns void +
    + +

    discardAll

    +
      +
    • discardAll(ids: readonly any[]): void
    • +
    +
      +
    • + +
      +
      +

      Discards the documents with the given IDs, so they won't appear in search + results

      +
      +

      It is equivalent to calling MiniSearch.discard for all the given IDs, + but with the optimization of triggering at most one automatic vacuuming at + the end.

      +

      Note: to remove all documents from the index, it is faster and more + convenient to call MiniSearch.removeAll with no argument, instead of + passing all IDs to this method.

      +
      +

      Parameters

      +
        +
      • +
        ids: readonly any[]
        +
      • +
      +

      Returns void

      +
    • +
    +

    has

    @@ -667,7 +703,7 @@

    has

  • @@ -699,7 +735,7 @@

    remove

  • @@ -737,7 +773,7 @@

    removeAll

  • @@ -772,7 +808,7 @@

    replace

  • @@ -811,7 +847,7 @@

    search

  • @@ -963,7 +999,7 @@

    toJSON

  • @@ -1003,7 +1039,7 @@

    vacuum

  • @@ -1064,7 +1100,7 @@

    Static getDefault

  • @@ -1110,7 +1146,7 @@

    Static loadJSON

  • @@ -1213,6 +1249,9 @@

    Returns discard

  • +
  • + discardAll +
  • has
  • diff --git a/docs/classes/_searchablemap_searchablemap_.searchablemap.html b/docs/classes/_searchablemap_searchablemap_.searchablemap.html index f5736f22..5cc6be93 100644 --- a/docs/classes/_searchablemap_searchablemap_.searchablemap.html +++ b/docs/classes/_searchablemap_searchablemap_.searchablemap.html @@ -153,7 +153,7 @@

    constructor

  • @@ -191,7 +191,7 @@

    size

  • @@ -218,7 +218,7 @@

    [Symbol.iterator]

  • @@ -242,7 +242,7 @@

    atPrefix

  • @@ -295,7 +295,7 @@

    clear

  • @@ -319,7 +319,7 @@

    delete

  • @@ -352,7 +352,7 @@

    entries

  • @@ -377,7 +377,7 @@

    fetch

  • @@ -432,7 +432,7 @@

    forEach

  • @@ -489,7 +489,7 @@

    fuzzyGet

  • @@ -547,7 +547,7 @@

    get

  • @@ -582,7 +582,7 @@

    has

  • @@ -616,7 +616,7 @@

    keys

  • @@ -641,7 +641,7 @@

    set

  • @@ -681,7 +681,7 @@

    update

  • @@ -748,7 +748,7 @@

    values

  • @@ -773,7 +773,7 @@

    Static from

  • @@ -811,7 +811,7 @@

    Static fromObject

  • diff --git a/docs/examples/app.js b/docs/examples/app.js index cf88343f..87417c7b 100644 --- a/docs/examples/app.js +++ b/docs/examples/app.js @@ -11,7 +11,7 @@ object-assign * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var r=n(0),a=n(1),l=n(5);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n
  • @@ -299,7 +299,7 @@

    SearchOptions

    SearchOptions: { boost?: undefined | {}; boostDocument?: undefined | ((documentId: any, term: string) => number); combineWith?: undefined | string; fields?: string[]; filter?: undefined | ((result: SearchResult) => boolean); fuzzy?: boolean | number | ((term: string, index: number, terms: string[]) => boolean | number); maxFuzzy?: undefined | number; prefix?: boolean | ((term: string, index: number, terms: string[]) => boolean); processTerm?: undefined | ((term: string) => string | string[] | null | undefined | false); tokenize?: undefined | ((text: string) => string[]); weights?: undefined | { fuzzy: number; prefix: number } }
    @@ -444,7 +444,7 @@

    SearchResult

    SearchResult: { id: any; match: MatchInfo; score: number; terms: string[] }
    @@ -506,7 +506,7 @@

    Suggestion

    Suggestion: { score: number; suggestion: string; terms: string[] }
    @@ -550,7 +550,7 @@

    VacuumConditions

    VacuumConditions: { minDirtCount?: undefined | number; minDirtFactor?: undefined | number }
    @@ -589,7 +589,7 @@

    VacuumOptions

    VacuumOptions: { batchSize?: undefined | number; batchWait?: undefined | number }
    diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index df949d1f..75b1b846 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -682,6 +682,39 @@ describe('MiniSearch', () => { }) }) + describe('discardAll', () => { + it('prevents the documents from appearing in search results', () => { + const ms = new MiniSearch({ fields: ['text'] }) + const documents = [ + { id: 1, text: 'Some interesting stuff' }, + { id: 2, text: 'Some more interesting stuff' }, + { id: 3, text: 'Some even more interesting stuff' } + ] + ms.addAll(documents) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([1, 2, 3]) + + ms.discardAll([1, 3]) + + expect(ms.search('stuff').map((doc) => doc.id)).toEqual([2]) + }) + + it('only triggers at most a single auto vacuum at the end', () => { + const ms = new MiniSearch({ fields: ['text'], autoVacuum: { minDirtCount: 3, minDirtFactor: 0, batchSize: 1, batchWait: 10 } }) + const documents = [] + for (const i = 1; i <= 10; i++) { + documents.push({ id: i, text: `Document ${i}` }) + } + ms.addAll(documents) + ms.discardAll([1, 2]) + expect(ms.isVacuuming).toEqual(false) + + ms.discardAll([3, 4, 5, 6, 7, 8, 9, 10]) + expect(ms.isVacuuming).toEqual(true) + expect(ms._enqueuedVacuum).toEqual(null) + }) + }) + describe('replace', () => { it('replaces an existing document with a new version', () => { const ms = new MiniSearch({ fields: ['text'] }) diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 79846497..21bc15ff 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -810,12 +810,44 @@ export default class MiniSearch { this._documentCount -= 1 this._dirtCount += 1 + this.maybeAutoVacuum() + } + + private maybeAutoVacuum (): void { if (this._options.autoVacuum === false) { return } const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor }) } + /** + * Discards the documents with the given IDs, so they won't appear in search + * results + * + * It is equivalent to calling [[MiniSearch.discard]] for all the given IDs, + * but with the optimization of triggering at most one automatic vacuuming at + * the end. + * + * Note: to remove all documents from the index, it is faster and more + * convenient to call [[MiniSearch.removeAll]] with no argument, instead of + * passing all IDs to this method. + */ + discardAll (ids: readonly any[]): void { + const autoVacuum = this._options.autoVacuum + + try { + this._options.autoVacuum = false + + for (const id of ids) { + this.discard(id) + } + } finally { + this._options.autoVacuum = autoVacuum + } + + this.maybeAutoVacuum() + } + /** * It replaces an existing document with the given updated version *