1
0
mirror of https://github.com/nextapps-de/flexsearch.git synced 2025-09-01 01:51:57 +02:00

support highlighting on resolver

This commit is contained in:
Thomas Wilkerling
2025-05-23 11:18:13 +02:00
parent 809119b492
commit db56fa1070
69 changed files with 5761 additions and 5038 deletions

View File

@@ -1,19 +1,23 @@
{
"reporter": "text",
"reports-dir": "./test/report/",
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80,
"exclude": [
"src/compress.js",
"src/db/indexeddb/**"
],
"src": [
"src"
],
"include": [
"test/*.js",
"src/**"
]
"reporter": ["text", "text-summary", "html"],
"reports-dir": "./test/report/",
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80,
"src": [
"src"
],
"include": [
"src/**"
],
"exclude": [
"test/*.js",
"src/compress.js",
"src/type.js",
"src/profiler.js",
"src/db/indexeddb/*",
"src/worker/node.js",
"src/worker/worker.js"
]
}

View File

@@ -842,62 +842,62 @@ if(!build_light) describe("Result Highlighting", function(){
it("Should have been highlighted merged results properly", function(){
// some test data
const data = [{
"id": 1,
"title": "Carmencita",
"description": "Description: Carmencita"
},{
"id": 2,
"title": "Le clown et ses chiens",
"description": "Description: Le clown et ses chiens"
}];
// create the document index
const index = new Document({
encoder: Charset.LatinBalance,
document: {
store: true,
index: [{
field: "title",
tokenize: "forward"
// some test data
const data = [{
"id": 1,
"title": "Carmencita",
"description": "Description: Carmencita"
},{
field: "description",
tokenize: "forward"
}]
}
});
"id": 2,
"title": "Le clown et ses chiens",
"description": "Description: Le clown et ses chiens"
}];
// add test data
for(let i = 0; i < data.length; i++){
index.add(data[i]);
}
// create the document index
const index = new Document({
encoder: Charset.LatinBalance,
document: {
store: true,
index: [{
field: "title",
tokenize: "forward"
},{
field: "description",
tokenize: "forward"
}]
}
});
let result = index.search({
query: "karmen or clown or not found",
suggest: true,
enrich: true,
merge: true,
highlight: "<b>$1</b>"
});
// add test data
for(let i = 0; i < data.length; i++){
index.add(data[i]);
}
expect(result).to.eql([{
id: 1,
doc: data[0],
field: ["title", "description"],
highlight: {
"title": '<b>Carmen</b>cita',
"description": 'Description: <b>Carmen</b>cita',
}
},{
id: 2,
doc: data[1],
field: ["title", "description"],
highlight: {
"title": 'Le <b>clown</b> et ses chiens',
"description": 'Description: Le <b>clown</b> et ses chiens',
}
}]);
let result = index.search({
query: "karmen or clown or not found",
suggest: true,
enrich: true,
merge: true,
highlight: "<b>$1</b>"
});
expect(result).to.eql([{
id: 1,
doc: data[0],
field: ["title", "description"],
highlight: {
"title": '<b>Carmen</b>cita',
"description": 'Description: <b>Carmen</b>cita',
}
},{
id: 2,
doc: data[1],
field: ["title", "description"],
highlight: {
"title": 'Le <b>clown</b> et ses chiens',
"description": 'Description: Le <b>clown</b> et ses chiens',
}
}]);
});
it("Should have been highlighted results properly (#480)", function(){

96
test/package-lock.json generated
View File

@@ -13,7 +13,7 @@
"mocha": "^11.1.0",
"mongodb": "^6.13.0",
"pg-promise": "^11.10.2",
"redis": "^4.7.0",
"redis": "^5.1.0",
"rollup": "^4.35.0",
"sqlite3": "^5.1.7",
"typescript": "^5.8.3"
@@ -211,62 +211,63 @@
}
},
"node_modules/@redis/bloom": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.1.0.tgz",
"integrity": "sha512-Gp5RWvVKbvItMU2sd848yhY/BnigToz8H4PYcvlBBSP5cQ3lVP1LMh5Kx2CYBNzCdDabVicwBKNvaoLBqPNqIg==",
"dev": true,
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@redis/client": "^1.0.0"
"@redis/client": "^5.1.0"
}
},
"node_modules/@redis/client": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz",
"integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@redis/client/-/client-5.1.0.tgz",
"integrity": "sha512-FMD35y2KgCWTBLOfF0MhwDSaIVcu5mOUuTV9Kw3JOWHMgON3+ulht31cjTB/gph0BfD1vzUvCeROeRaf/d+35w==",
"dev": true,
"dependencies": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
"yallist": "4.0.0"
"cluster-key-slot": "1.1.2"
},
"engines": {
"node": ">=14"
}
},
"node_modules/@redis/graph": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
"dev": true,
"peerDependencies": {
"@redis/client": "^1.0.0"
"node": ">= 18"
}
},
"node_modules/@redis/json": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
"integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@redis/json/-/json-5.1.0.tgz",
"integrity": "sha512-laXZt1Rlimk3py5ZoABBnd4xn/8dWbLUWGvVS7avgMhdczS+eWtXpElilJbFpc+7ZpVlol4vaSGFuR8ThDcTFw==",
"dev": true,
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@redis/client": "^1.0.0"
"@redis/client": "^5.1.0"
}
},
"node_modules/@redis/search": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
"integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@redis/search/-/search-5.1.0.tgz",
"integrity": "sha512-afQYMeIdWGNPjr84GxxgJVkolxMW3BBrlNOwhRHPdzbdGh0rTUPjOJpGHBig34ostHX6AhZ6QwqceU1zLluDEg==",
"dev": true,
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@redis/client": "^1.0.0"
"@redis/client": "^5.1.0"
}
},
"node_modules/@redis/time-series": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
"integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.1.0.tgz",
"integrity": "sha512-BjKndLXREPeb4ZtxrI6z1bz2FbzBj7LnWyyevNk6Wd7VRWQ3W10LSvJAJwguPD62mSqpTPhy0lMPqFJwo0gS7A==",
"dev": true,
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@redis/client": "^1.0.0"
"@redis/client": "^5.1.0"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
@@ -1588,15 +1589,6 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/generic-pool": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -3179,17 +3171,19 @@
}
},
"node_modules/redis": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz",
"integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/redis/-/redis-5.1.0.tgz",
"integrity": "sha512-5G5k9sYo5H5L0kd7UETiJZFTkIClH31fSmaEk2eU8E7mrmF0J1t6RqmFXOCJmSRlNd3QyvDUK/AWL9psbKaN0Q==",
"dev": true,
"dependencies": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.6.0",
"@redis/graph": "1.1.1",
"@redis/json": "1.0.7",
"@redis/search": "1.2.0",
"@redis/time-series": "1.1.0"
"@redis/bloom": "5.1.0",
"@redis/client": "5.1.0",
"@redis/json": "5.1.0",
"@redis/search": "5.1.0",
"@redis/time-series": "5.1.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/request": {

View File

@@ -18,7 +18,7 @@
"mocha": "^11.1.0",
"mongodb": "^6.13.0",
"pg-promise": "^11.10.2",
"redis": "^4.7.0",
"redis": "^5.1.0",
"rollup": "^4.35.0",
"sqlite3": "^5.1.7",
"typescript": "^5.8.3"

View File

@@ -10,11 +10,12 @@ const build_compact = env && env.includes(".compact");
const build_esm = !env || env.startsWith("module");
const Charset = _Charset || (await import("../src/charset.js")).default;
import Clickhouse from "flexsearch/db/clickhouse";
import Clickhouse_src from "../src/db/clickhouse/index.js";
import Clickhouse_dist from "../dist/module/db/clickhouse/index.js";
import tests from "./persistent.js";
if(!build_light && !build_compact){
describe("Persistent: Clickhouse", function(){
tests(Clickhouse, "Clickhouse");
tests(env ? Clickhouse_dist : Clickhouse_src, "Clickhouse");
});
}

View File

@@ -236,18 +236,13 @@ export default function(DB, DBClass){
// mount database to the index
await document.mount(db);
await document.clear();
expect(document.index.get("primaryTitle").db).to.be.instanceof(db.constructor);
expect(document.index.get("originalTitle").db).to.be.instanceof(db.constructor);
expect(document.index.get("startYear").db).to.be.instanceof(db.constructor);
expect(document.index.get("genres").db).to.be.instanceof(db.constructor);
//await document.destroy();
//expect(document.index.get("primaryTitle").db).to.be.instanceof(db.constructor);
// mount database to the index
//await db.mount(document);
//expect(document.index.get("primaryTitle").db).to.be.instanceof(db.constructor);
//await document.clear();
// add test data
for(let i = 0; i < data.length; i++){
document.add(data[i]);
@@ -270,7 +265,6 @@ export default function(DB, DBClass){
// transfer changes in bulk
await document.commit();
//await new Promise(resolve => setTimeout(resolve, 200));
expect(document.index.get("primaryTitle").reg.size).to.equal(0);
expect(document.index.get("primaryTitle").map.size).to.equal(0);
@@ -382,6 +376,17 @@ export default function(DB, DBClass){
field: [ 'primaryTitle', 'originalTitle' ]
});
await document.clear();
result = await document.search({
query: "karmen or clown or nothing",
suggest: true,
enrich: true,
merge: true
});
expect(result).to.eql([]);
for(const index of document.index.values()){
index.destroy();
index.db.close();
@@ -400,7 +405,7 @@ export default function(DB, DBClass){
}];
// create the document index
const index = new Document({
const document = new Document({
cache: true,
db: new DB("test-highlight", {
type: "Integer"
@@ -415,18 +420,18 @@ export default function(DB, DBClass){
}
});
//await index.mount(db);
await index.db;
//await document.mount(db);
await document.db;
// add test data
for(let i = 0; i < data.length; i++){
index.add(data[i]);
document.add(data[i]);
}
await index.commit();
await document.commit();
// perform a query
let result = await index.searchCache({
let result = await document.searchCache({
query: "karmen or clown or not found",
suggest: true,
highlight: "<b>$1</b>"
@@ -443,7 +448,7 @@ export default function(DB, DBClass){
}]);
// perform a query on cache
result = await index.searchCache({
result = await document.searchCache({
query: "karmen or clown or not found",
suggest: true,
highlight: "<b>$1</b>"
@@ -460,7 +465,7 @@ export default function(DB, DBClass){
}]);
// perform a query using pluck
result = await index.search({
result = await document.search({
query: "karmen or clown or not found",
suggest: true,
field: "title",
@@ -476,6 +481,11 @@ export default function(DB, DBClass){
doc: data[1],
highlight: 'Le <b>clown</b> et ses chiens'
}]);
for(const index of document.index.values()){
index.destroy();
index.db.close();
}
});
it("Resolver (Persistent)", async function(){
@@ -492,7 +502,7 @@ export default function(DB, DBClass){
}];
// create the document index
const index = new Document({
const document = new Document({
db: new DB("test-store", {
type: "integer"
}),
@@ -509,78 +519,77 @@ export default function(DB, DBClass){
}
});
await index.db;
await document.db;
// add test data
for(let i = 0; i < data.length; i++){
index.add(data[i]);
document.add(data[i]);
}
await index.commit();
await document.commit();
let result = new Resolver({
index: index,
query: "karmen",
field: "title"
index: document,
query: "not found",
field: "description"
});
expect(result).to.be.instanceof(Resolver);
result = result.or({
query: "clown",
pluck: "description",
});
result = result.and({
query: "not found",
field: "title",
query: "karmen or clown",
pluck: "title",
suggest: true,
enrich: true,
resolve: true,
// TODO
//highlight: "<b>$1</b>"
highlight: "<b>$1</b>"
});
expect(result).to.be.instanceof(Promise);
expect(await result).to.eql([{
id: 1,
doc: data[0],
//highlight: "<b>Carmen</b>cita"
highlight: "<b>Carmen</b>cita"
},{
id: 2,
doc: data[1],
//highlight: "Le <b>clown</b> et ses chiens"
highlight: "Le <b>clown</b> et ses chiens"
}]);
// -----------------------------------
result = new Resolver({
index: index,
query: "karmen",
field: "title"
index: document,
query: "not found",
field: "description"
});
expect(result).to.be.instanceof(Resolver);
result = result.or({
query: "clown",
pluck: "description",
}).and({
query: "not found",
field: "title",
query: "karmen or clown",
pluck: "title",
suggest: true
}).resolve({
enrich: true
enrich: true,
highlight: "<b>$1</b>"
});
expect(result).to.be.instanceof(Promise);
expect(await result).to.eql([{
id: 1,
doc: data[0]
doc: data[0],
highlight: "<b>Carmen</b>cita"
},{
id: 2,
doc: data[1]
doc: data[1],
highlight: "Le <b>clown</b> et ses chiens"
}]);
for(const index of document.index.values()){
index.destroy();
index.db.close();
}
});
it("Should have been resolved a Resolver properly (Async)", async function(){
@@ -744,6 +753,9 @@ export default function(DB, DBClass){
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.have.members([3, 1, 2]);
await index.destroy();
await index.db.close();
});
it("Should have been resolved a Resolver properly (Document Persistent)", async function(){
@@ -774,6 +786,7 @@ export default function(DB, DBClass){
// mount database to the index
await document.mount(db);
await document.clear();
// add test data
for(let i = 0; i < data.length; i++){
@@ -926,180 +939,11 @@ export default function(DB, DBClass){
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000001", "tt0000002"]);
});
it("Should have been resolved a Resolver properly (Document Worker)", async function(){
// create the document index
const document = await new Document({
worker: true,
encoder: Charset.LatinBalance,
document: {
id: "tconst",
store: true,
index: [{
field: "primaryTitle",
tokenize: "forward"
},{
field: "originalTitle",
tokenize: "forward"
}],
tag: [{
field: "startYear"
},{
field: "genres"
}]
}
});
// add test data
for(let i = 0; i < data.length; i++){
await document.addAsync(data[i]);
for(const index of document.index.values()){
index.destroy();
index.db.close();
}
let resolver = new Resolver({
index: document,
query: "karmen or clown or nothing",
field: "primaryTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
expect(resolver.result).to.eql([]);
expect(resolver.await).to.be.instanceof(Promise);
let tmp = resolver.await;
resolver = resolver.resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.have.members(["tt0000001", "tt0000002"]);
expect((await tmp)[0]).to.have.members(["tt0000001"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen or clown or nothing",
field: "primaryTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
expect(resolver.result).to.eql([]);
expect(resolver.await).to.be.instanceof(Promise);
tmp = resolver.await;
resolver = resolver.resolve({ enrich: true });
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql([{
id: data[0].tconst,
doc: data[0]
}, {
id: data[1].tconst,
doc: data[1]
}]);
expect((await tmp)[0]).to.have.members(["tt0000001"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen or clown or nothing",
field: "primaryTitle",
suggest: true
}).or({
index: document,
queue: true,
query: "karmen or clown or nothing",
pluck: "primaryTitle",
suggest: true,
enrich: true,
resolve: true
});
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql([{
id: data[0].tconst,
doc: data[0]
}, {
id: data[1].tconst,
doc: data[1]
}]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen or clown or nothing",
pluck: "primaryTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
expect(resolver.result).to.eql([]);
expect(resolver.await).to.be.instanceof(Promise);
resolver = resolver.resolve({
limit: 1,
offset: 1
});
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000002"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen",
pluck: "primaryTitle"
}).or({
queue: true,
cache: true,
query: "clown",
field: "originalTitle"
}).and({
async: true,
query: "not found",
pluck: "originalTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
resolver = resolver.resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000001", "tt0000002"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
// TODO
//cache: true,
query: "karmen",
pluck: "primaryTitle"
}).or({
and: [{
async: true,
//cache: true,
query: "not found",
pluck: "originalTitle",
suggest: true
},{
queue: true,
//cache: true,
query: "clown",
field: "originalTitle",
suggest: true
}]
}).resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000001", "tt0000002"]);
});
it("Should have been resolved a Resolver properly (Queue)", async function(){
@@ -1165,11 +1009,11 @@ export default function(DB, DBClass){
index: index,
async: true,
query: "bar"
}).and({
}).limit(3).and({
queue: true,
query: "foo",
suggest: true
});
}).limit(3);
expect(resolver).to.be.instanceof(Resolver);
resolver = resolver.resolve();
@@ -1179,6 +1023,24 @@ export default function(DB, DBClass){
// -----------------------------------
resolver = new Resolver({
index: index,
async: true,
query: "bar"
}).boost(2).and({
queue: true,
query: "foo",
suggest: true
}).offset(1).limit(1);
expect(resolver).to.be.instanceof(Resolver);
resolver = resolver.resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.have.members([1]);
// -----------------------------------
resolver = new Resolver({
index: index,
queue: true,
@@ -1264,5 +1126,46 @@ export default function(DB, DBClass){
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.have.members([3, 1, 2]);
await index.destroy();
await index.db.close();
});
it("#504", async function(){
const document = new Document({
tokenize: "forward",
commit: true,
document: {
id: "id",
index: ["name", "shortName"],
store: true,
},
});
const db = new DB("mystore", { type: "integer" });
await document.mount(db);
await document.clear();
document.add({
id: 1,
name: "a name",
shortName: "" // Or undefined
});
await document.commit();
const result = await document.search({
query: "name"
});
expect(result).to.eql([
{ field: 'name', result: [ 1 ] }
]);
for(const index of document.index.values()){
index.destroy();
index.db.close();
}
});
}

View File

@@ -10,11 +10,12 @@ const build_compact = env && env.includes(".compact");
const build_esm = !env || env.startsWith("module");
const Charset = _Charset || (await import("../src/charset.js")).default;
import Mongo from "flexsearch/db/mongodb";
import Mongo_src from "../src/db/mongodb/index.js";
import Mongo_dist from "../dist/module/db/mongodb/index.js";
import tests from "./persistent.js";
if(!build_light && !build_compact){
describe("Persistent: Mongo", function(){
tests(Mongo, "Mongo");
tests(env ? Mongo_dist : Mongo_src, "Mongo");
});
}

View File

@@ -10,11 +10,12 @@ const build_compact = env && env.includes(".compact");
const build_esm = !env || env.startsWith("module");
const Charset = _Charset || (await import("../src/charset.js")).default;
import Postgres from "flexsearch/db/postgres";
import Postgres_src from "../src/db/postgres/index.js";
import Postgres_dist from "../dist/module/db/postgres/index.js";
import tests from "./persistent.js";
if(!build_light && !build_compact){
describe("Persistent: Postgres", function(){
tests(Postgres, "Postgres");
tests(env ? Postgres_dist : Postgres_src, "Postgres");
});
}

View File

@@ -10,11 +10,12 @@ const build_compact = env && env.includes(".compact");
const build_esm = !env || env.startsWith("module");
const Charset = _Charset || (await import("../src/charset.js")).default;
import Redis from "flexsearch/db/redis";
import Redis_src from "../src/db/redis/index.js";
import Redis_dist from "../dist/module/db/redis/index.js";
import tests from "./persistent.js";
if(!build_light && !build_compact){
describe("Persistent: Redis", function(){
tests(Redis, "Redis");
tests(env ? Redis_dist : Redis_src, "Redis");
});
}

View File

@@ -10,11 +10,12 @@ const build_compact = env && env.includes(".compact");
const build_esm = !env || env.startsWith("module");
const Charset = _Charset || (await import("../src/charset.js")).default;
import SQLite from "flexsearch/db/sqlite";
import SQLite_src from "../src/db/sqlite/index.js";
import SQLite_dist from "../dist/module/db/sqlite/index.js";
import tests from "./persistent.js";
if(!build_light && !build_compact){
describe("Persistent: SQLite", function(){
tests(SQLite, "SQLite");
tests(env ? SQLite_dist : SQLite_src, "SQLite");
});
}

View File

@@ -16,6 +16,11 @@ import {
DocumentData
} from "flexsearch";
test_index();
test_document();
test_persistent();
test_worker();
async function test_index() {
const index = new Index();

View File

@@ -100,6 +100,289 @@ if(!build_light && !build_compact) describe("Worker", function(){
expect(await index.search("bar")).to.have.lengthOf(0);
expect(await index.search("foobar")).to.have.lengthOf(0);
});
it("Result Highlighting", async function(){
// some test data
const data = [{
"id": 1,
"title": "Carmencita"
},{
"id": 2,
"title": "Le clown et ses chiens"
}];
// create the document index
const document = await new Document({
worker: true,
document: {
store: true,
index: [{
field: "title",
tokenize: "forward",
encoder: Charset.LatinBalance
}]
}
});
// add test data
for(let i = 0; i < data.length; i++){
await document.add(data[i]);
}
// perform a query
let result = await document.searchCache({
query: "karmen or clown or not found",
suggest: true,
highlight: "<b>$1</b>"
});
expect(result[0].result).to.eql([{
id: 1,
doc: data[0],
highlight: '<b>Carmen</b>cita'
},{
id: 2,
doc: data[1],
highlight: 'Le <b>clown</b> et ses chiens'
}]);
// perform a query on cache
result = await document.searchCache({
query: "karmen or clown or not found",
suggest: true,
highlight: "<b>$1</b>"
});
expect(result[0].result).to.eql([{
id: 1,
doc: data[0],
highlight: '<b>Carmen</b>cita'
}, {
id: 2,
doc: data[1],
highlight: 'Le <b>clown</b> et ses chiens'
}]);
// perform a query using pluck
result = await document.search({
query: "karmen or clown or not found",
suggest: true,
field: "title",
highlight: "<b>$1</b>"
});
expect(result[0].result).to.eql([{
id: 1,
doc: data[0],
highlight: '<b>Carmen</b>cita'
},{
id: 2,
doc: data[1],
highlight: 'Le <b>clown</b> et ses chiens'
}]);
});
it("Should have been resolved a Resolver properly (Document Worker)", async function(){
const data = [{
"tconst": "tt0000001",
"titleType": "short",
"primaryTitle": "Carmencita",
"originalTitle": "Carmencita",
"isAdult": 0,
"startYear": "1894",
"endYear": "",
"runtimeMinutes": "1",
"genres": [
"Documentary",
"Short"
]
},{
"tconst": "tt0000002",
"titleType": "short",
"primaryTitle": "Le clown et ses chiens",
"originalTitle": "Le clown et ses chiens",
"isAdult": 0,
"startYear": "1892",
"endYear": "",
"runtimeMinutes": "5",
"genres": [
"Animation",
"Short"
]
}];
// create the document index
const document = await new Document({
worker: true,
encoder: Charset.LatinBalance,
document: {
id: "tconst",
store: true,
index: [{
field: "primaryTitle",
tokenize: "forward"
},{
field: "originalTitle",
tokenize: "forward"
}],
tag: [{
field: "startYear"
},{
field: "genres"
}]
}
});
// add test data
for(let i = 0; i < data.length; i++){
await document.addAsync(data[i]);
}
let resolver = new Resolver({
index: document,
query: "karmen or clown or nothing",
field: "primaryTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
expect(resolver.result).to.eql([]);
expect(resolver.await).to.be.instanceof(Promise);
let tmp = resolver.await;
resolver = resolver.resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.have.members(["tt0000001", "tt0000002"]);
expect((await tmp)[0]).to.have.members(["tt0000001"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen or clown or nothing",
field: "primaryTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
expect(resolver.result).to.eql([]);
expect(resolver.await).to.be.instanceof(Promise);
tmp = resolver.await;
resolver = resolver.resolve({ enrich: true });
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql([{
id: data[0].tconst,
doc: data[0]
}, {
id: data[1].tconst,
doc: data[1]
}]);
expect((await tmp)[0]).to.have.members(["tt0000001"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen or clown or nothing",
field: "primaryTitle",
suggest: true
}).or({
index: document,
queue: true,
query: "karmen or clown or nothing",
pluck: "primaryTitle",
suggest: true,
enrich: true,
resolve: true
});
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql([{
id: data[0].tconst,
doc: data[0]
}, {
id: data[1].tconst,
doc: data[1]
}]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen or clown or nothing",
pluck: "primaryTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
expect(resolver.result).to.eql([]);
expect(resolver.await).to.be.instanceof(Promise);
resolver = resolver.resolve({
limit: 1,
offset: 1
});
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000002"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
query: "karmen",
pluck: "primaryTitle"
}).or({
queue: true,
cache: true,
query: "clown",
field: "originalTitle"
}).and({
async: true,
query: "not found",
pluck: "originalTitle",
suggest: true
});
expect(resolver).to.be.instanceof(Resolver);
resolver = resolver.resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000001", "tt0000002"]);
// -----------------------------------
resolver = new Resolver({
index: document,
async: true,
cache: true,
query: "karmen",
pluck: "primaryTitle"
}).or({
and: [{
async: true,
cache: true,
query: "not found",
pluck: "originalTitle",
suggest: true
},{
queue: true,
cache: true,
query: "clown",
field: "originalTitle",
suggest: true
}]
}).resolve();
expect(resolver).to.be.instanceof(Promise);
expect(await resolver).to.eql(["tt0000001", "tt0000002"]);
});
});