-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(full-text-search): add full-text-search as separate package (#35)
- Loading branch information
Showing
28 changed files
with
5,176 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,5 +23,6 @@ module.exports = { | |
"always" | ||
], | ||
"arrow-parens": [2, "always"], | ||
"no-constant-condition": 0 | ||
} | ||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "@lokijs/full-text-search", | ||
"description": "A full text search engine.", | ||
"author": "Various authors", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/LokiJS-Forge/LokiJS2.git" | ||
}, | ||
"main": "lokijs.full-text-search.js", | ||
"optionalDependencies": { | ||
"@lokijs/loki": "0" | ||
} | ||
} |
166 changes: 166 additions & 0 deletions
166
packages/full-text-search/spec/generic/inverted_index.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/* global describe, it, expect */ | ||
import {InvertedIndex} from "../../src/inverted_index"; | ||
|
||
describe("inverted index", () => { | ||
|
||
let ii = new InvertedIndex(); | ||
|
||
let field1 = "Hello world, how are you today?!"; | ||
let field2 = "Well done world..."; | ||
let field3 = "I am good, and you?"; | ||
let field4 = "Now again inside today! You..."; | ||
let field5 = "Good bye NO! for all worlds..."; | ||
|
||
it ("get", () => { | ||
expect(ii.documentCount).toBeNumber(); | ||
expect(ii.documentStore).toBeObject(); | ||
expect(ii.totalFieldLength).toBeNumber(); | ||
expect(ii.tokenizer).toBeObject(); | ||
expect(ii.root).toBeObject(); | ||
}); | ||
|
||
it("insert", () => { | ||
ii.insert(field1, 1); | ||
expect(() =>ii.insert(field2, 1)).toThrowErrorOfType("Error"); | ||
ii.insert(field3, 2); | ||
|
||
ii.tokenizer.add("bad_tokenizer", () => [""]); | ||
ii.insert(field4, 3); | ||
ii.tokenizer.remove("bad_tokenizer"); | ||
ii.insert(field4, 4); | ||
ii.insert(field5, 5); | ||
}); | ||
|
||
it("remove", () => { | ||
ii.remove(1); | ||
ii.remove(4); | ||
ii.remove(15); | ||
}); | ||
|
||
it("getTermIndex", () => { | ||
expect(InvertedIndex.getTermIndex("you", ii.root)).not.toBe(null); | ||
expect(InvertedIndex.getTermIndex("ayou", ii.root, 1)).not.toBe(null); | ||
expect(InvertedIndex.getTermIndex("you", ii.root, 10)).toBe(null); | ||
expect(InvertedIndex.getTermIndex("xyz1234", ii.root)).toBe(null); | ||
}); | ||
|
||
it("getNextTermIndex", () => { | ||
InvertedIndex.getNextTermIndex(ii.root); | ||
let idx = InvertedIndex.getTermIndex("you", ii.root); | ||
expect(InvertedIndex.getNextTermIndex(idx)).not.toBe(null); | ||
}); | ||
|
||
it("extendTermIndex", () => { | ||
expect(InvertedIndex.extendTermIndex(ii.root)).toBeArray(); | ||
}); | ||
|
||
it("serialize", () => { | ||
let ii1 = new InvertedIndex(); | ||
ii1.insert(field1, 1); | ||
ii1.insert(field2, 2); | ||
ii1.insert(field3, 3); | ||
|
||
let ii2 = new InvertedIndex(); | ||
ii2.insert(field1, 1); | ||
ii2.insert(field2, 2); | ||
ii2.insert(field3, 3); | ||
ii2.insert(field4, 4); | ||
|
||
let ii3 = InvertedIndex.fromJSONObject(JSON.parse(JSON.stringify(ii2))); | ||
|
||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
ii2.remove(4); | ||
ii3.remove(4); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
|
||
ii2.remove(1); | ||
ii3.remove(2); | ||
expect(JSON.stringify(ii2)).not.toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).not.toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).not.toEqual(JSON.stringify(ii2)); | ||
|
||
ii1.remove(1); | ||
ii1.remove(2); | ||
ii2.remove(2); | ||
ii3.remove(1); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
|
||
ii2 = InvertedIndex.fromJSONObject(JSON.parse(JSON.stringify(ii1))); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
|
||
ii1.insert(field5, 5); | ||
expect(JSON.stringify(ii2)).not.toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).not.toEqual(JSON.stringify(ii1)); | ||
|
||
ii1.remove(5); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
|
||
// Check if still can be used | ||
ii3.insert(field5, 6); | ||
ii3.remove(6); | ||
}); | ||
|
||
it("serialize without optimization", () => { | ||
let ii1 = new InvertedIndex({optimizeChanges: false}); | ||
ii1.insert(field1, 1); | ||
ii1.insert(field2, 2); | ||
ii1.insert(field3, 3); | ||
|
||
let ii2 = new InvertedIndex({optimizeChanges: false}); | ||
ii2.insert(field1, 1); | ||
ii2.insert(field2, 2); | ||
ii2.insert(field3, 3); | ||
ii2.insert(field4, 4); | ||
|
||
let ii3 = InvertedIndex.fromJSONObject(JSON.parse(JSON.stringify(ii2))); | ||
|
||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
ii2.remove(4); | ||
ii3.remove(4); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
|
||
ii2.remove(1); | ||
ii3.remove(2); | ||
expect(JSON.stringify(ii2)).not.toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).not.toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).not.toEqual(JSON.stringify(ii2)); | ||
|
||
// Compare with optimized inverted index. | ||
let iio3 = new InvertedIndex(); | ||
iio3.insert(field1, 1); | ||
iio3.insert(field3, 3); | ||
expect(JSON.stringify(ii3.root)).toEqual(JSON.stringify(iio3.root)); | ||
|
||
ii1.remove(1); | ||
ii1.remove(2); | ||
ii2.remove(2); | ||
ii3.remove(1); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
|
||
ii2 = InvertedIndex.fromJSONObject(JSON.parse(JSON.stringify(ii1))); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
|
||
ii1.insert(field5, 5); | ||
expect(JSON.stringify(ii2)).not.toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).not.toEqual(JSON.stringify(ii1)); | ||
|
||
ii1.remove(5); | ||
expect(JSON.stringify(ii2)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii1)); | ||
expect(JSON.stringify(ii3)).toEqual(JSON.stringify(ii2)); | ||
|
||
// Check if still can be used | ||
ii3.insert(field5, 6); | ||
ii3.remove(6); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import {DE} from "../../../src/language/de"; | ||
|
||
export const de = { | ||
tokenizer: DE, | ||
docs: [ | ||
"An Deutschland grenzen neun Nachbarländer und naturräumlich im Norden die Gewässer der Nord- und Ostsee, im Süden das Bergland der Alpen. Es liegt in der gemäßigten Klimazone, zählt mit rund 80 Millionen Einwohnern zu den dicht besiedelten Flächenstaaten und gilt international als das Land mit der dritthöchsten Zahl von Einwanderern. aufeinanderfolgenden. auffassen.", | ||
"Deutschland als Urlaubsziel verfügt über günstige Voraussetzungen: Gebirgslandschaften (Alpen und Mittelgebirge), See- und Flusslandschaften, die Küsten und Inseln der Nord- und Ostsee, zahlreiche Kulturdenkmäler und eine Vielzahl geschichtsträchtiger Städte sowie gut ausgebaute Infrastruktur. Vorteilhaft ist die zentrale Lage in Europa." | ||
], | ||
tests: [{ | ||
what: "find the word", | ||
search: "deutschland", | ||
found: [0, 1] | ||
}, { | ||
what: "find the word", | ||
search: "urlaubsziel", | ||
found: [1] | ||
}, { | ||
what: "find the word", | ||
search: "gewass", | ||
found: [0] | ||
}, { | ||
what: "find the word", | ||
search: "verfugt", | ||
found: [1] | ||
}, { | ||
what: "never find a word that does not exist, like", | ||
search: "inexistent", | ||
found: [] | ||
}, { | ||
what: "never find a stop word like", | ||
search: "und", | ||
found: [] | ||
}, { | ||
what: "find a correctly stemmed word", | ||
search: "auffassung", | ||
found: [0] | ||
}] | ||
}; |
Oops, something went wrong.