From 884a64fe79b75ded87498deaba55f9e4880522bc Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Fri, 19 Aug 2022 20:47:06 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/components/Search/Search.vue | 9 ++- package-lock.json | 14 ++--- package.json | 2 +- server/core/DbSearcher.js | 85 +++++++++++++++++++++++++---- 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/client/components/Search/Search.vue b/client/components/Search/Search.vue index 0a2723c..cec7c14 100644 --- a/client/components/Search/Search.vue +++ b/client/components/Search/Search.vue @@ -46,7 +46,12 @@
- Показаны {{ queryFound }} из {{ totalFound }} найденных авторов +
+ Показаны {{ queryFound }} из {{ totalFound }} найденных авторов +
+
+ Ничего не найдено +
@@ -135,7 +140,7 @@ class Search { limit = 100; //stuff - queryFound = 0; + queryFound = -1; totalFound = 0; limitOptions = [ diff --git a/package-lock.json b/package-lock.json index 0e9177f..8fd04ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "compression": "^1.7.4", "express": "^4.18.1", "fs-extra": "^10.1.0", - "jembadb": "^4.0.0", + "jembadb": "^4.1.0", "localforage": "^1.10.0", "lodash": "^4.17.21", "minimist": "^1.2.6", @@ -5103,9 +5103,9 @@ } }, "node_modules/jembadb": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jembadb/-/jembadb-4.0.0.tgz", - "integrity": "sha512-FLOL1uBhtUSOy/NngbzIsKSHaM6DISSNHpCT+NApsPj1ExCWnXsym0rs9TJum75Hdu48HP34UUtfQKyFo2Sseg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jembadb/-/jembadb-4.1.0.tgz", + "integrity": "sha512-0A35t0S/ofTkTa5++gWtL1ctTimYgvcs84IV3TL5TFQzGmv2OFhIy8FVz0chBwcb6aTp161ec/yFSzN4ISySAA==", "engines": { "node": ">=16.16.0" } @@ -12577,9 +12577,9 @@ "dev": true }, "jembadb": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jembadb/-/jembadb-4.0.0.tgz", - "integrity": "sha512-FLOL1uBhtUSOy/NngbzIsKSHaM6DISSNHpCT+NApsPj1ExCWnXsym0rs9TJum75Hdu48HP34UUtfQKyFo2Sseg==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jembadb/-/jembadb-4.1.0.tgz", + "integrity": "sha512-0A35t0S/ofTkTa5++gWtL1ctTimYgvcs84IV3TL5TFQzGmv2OFhIy8FVz0chBwcb6aTp161ec/yFSzN4ISySAA==" }, "jest-worker": { "version": "27.5.1", diff --git a/package.json b/package.json index bc9b3c8..dc7ff03 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "compression": "^1.7.4", "express": "^4.18.1", "fs-extra": "^10.1.0", - "jembadb": "^4.0.0", + "jembadb": "^4.1.0", "localforage": "^1.10.0", "lodash": "^4.17.21", "minimist": "^1.2.6", diff --git a/server/core/DbSearcher.js b/server/core/DbSearcher.js index a7e06cb..eab24d4 100644 --- a/server/core/DbSearcher.js +++ b/server/core/DbSearcher.js @@ -3,6 +3,9 @@ const utils = require('./utils'); const maxUtf8Char = String.fromCodePoint(0xFFFFF); +const ruAlphabet = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'; +const enAlphabet = 'abcdefghijklmnopqrstuvwxyz'; +const enruArr = (ruAlphabet + enAlphabet).split(''); class DbSearcher { constructor(config, db) { @@ -16,31 +19,53 @@ class DbSearcher { this.periodicCleanCache();//no await } + getWhere(a) { + const db = this.db; + let where; + + //особая обработка префиксов + if (a[0] == '=') { + a = a.substring(1); + where = `@@dirtyIndexLR('value', ${db.esc(a)}, ${db.esc(a)});`; + } else if (a[0] == '*') { + a = a.substring(1); + where = `@@indexIter('value', (v) => (v.indexOf(${db.esc(a)}) >= 0) );`; + } else if (a[0] == '#') { + a = a.substring(1); + where = `@@indexIter('value', (v) => { + const enru = new Set(${db.esc(enruArr)}); + return !v || !enru.has(v[0].toLowerCase()); + });`; + } else { + where = `@@dirtyIndexLR('value', ${db.esc(a)}, ${db.esc(a + maxUtf8Char)});`; + } + + return where; + } + async selectAuthorIds(query) { const db = this.db; - let authorRows; let authorIds = new Set(); + //сначала выберем все id авторов по фильтру //порядок id соответсвует ASC-сортировке по author - if (query.author) { - const a = query.author.toLowerCase(query.author); + if (query.author && query.author !== '*') { + const where = this.getWhere(query.author.toLowerCase()); - authorRows = await db.select({ + const authorRows = await db.select({ table: 'author', - map: `(r) => ({id: r.id})`, - where: ` - @@dirtyIndexLR('value', ${db.esc(a)}, ${db.esc(a + maxUtf8Char)}) - `, + dirtyIdsOnly: true, + where }); for (const row of authorRows) authorIds.add(row.id); } else {//все авторы if (!db.searchCache.authorIdsAll) { - authorRows = await db.select({ + const authorRows = await db.select({ table: 'author', - map: `(r) => ({id: r.id})`, + dirtyIdsOnly: true, }); db.searchCache.authorIdsAll = []; @@ -59,7 +84,45 @@ class DbSearcher { idsArr.push(authorIds); //серии + if (query.series && query.series !== '*') { + const where = this.getWhere(query.series.toLowerCase()); + + const seriesRows = await db.select({ + table: 'series', + map: `(r) => ({authorId: r.authorId})`, + where + }); + + let ids = new Set(); + for (const row of seriesRows) { + for (const id of row.authorId) + ids.add(id); + + } + + idsArr.push(ids); + } + //названия + if (query.title && query.title !== '*') { + const where = this.getWhere(query.title.toLowerCase()); + + const seriesRows = await db.select({ + table: 'title', + map: `(r) => ({authorId: r.authorId})`, + where + }); + + let ids = new Set(); + for (const row of seriesRows) { + for (const id of row.authorId) + ids.add(id); + + } + + idsArr.push(ids); + } + //жанры //языки @@ -69,7 +132,7 @@ class DbSearcher { //сортировка authorIds = Array.from(authorIds); - authorIds.sort((a, b) => a > b); + authorIds.sort((a, b) => a - b); return authorIds; }