Улучшение поисковой БД

This commit is contained in:
Book Pauk
2022-08-24 22:45:24 +07:00
parent 102e584850
commit 22506a91f4
2 changed files with 60 additions and 59 deletions

View File

@@ -11,16 +11,14 @@ class DbCreator {
async run(db, callback) { async run(db, callback) {
const config = this.config; const config = this.config;
//book
await db.create({
table: 'book'
});
callback({job: 'load inpx', jobMessage: 'Загрузка INPX'}); callback({job: 'load inpx', jobMessage: 'Загрузка INPX'});
const readFileCallback = async(readState) => { const readFileCallback = async(readState) => {
callback(readState); callback(readState);
}; };
//временная таблица
let bookArr = [];
//поисковые таблицы, ниже сохраним в БД //поисковые таблицы, ниже сохраним в БД
let authorMap = new Map();//авторы let authorMap = new Map();//авторы
let authorArr = []; let authorArr = [];
@@ -41,7 +39,6 @@ class DbCreator {
//stuff //stuff
let recsLoaded = 0; let recsLoaded = 0;
let id = 0;
let chunkNum = 0; let chunkNum = 0;
const splitAuthor = (author) => { const splitAuthor = (author) => {
@@ -58,7 +55,8 @@ class DbCreator {
const parsedCallback = async(chunk) => { const parsedCallback = async(chunk) => {
for (const rec of chunk) { for (const rec of chunk) {
rec.id = ++id; const id = bookArr.length;
bookArr.push(rec);
if (!rec.del) { if (!rec.del) {
bookCount++; bookCount++;
@@ -97,8 +95,6 @@ class DbCreator {
} }
} }
await db.insert({table: 'book', rows: chunk});
recsLoaded += chunk.length; recsLoaded += chunk.length;
callback({recsLoaded}); callback({recsLoaded});
@@ -117,7 +113,7 @@ class DbCreator {
callback({job: 'author sort', jobMessage: 'Сортировка'}); callback({job: 'author sort', jobMessage: 'Сортировка'});
authorArr.sort((a, b) => a.value.localeCompare(b.value)); authorArr.sort((a, b) => a.value.localeCompare(b.value));
id = 0; let id = 0;
authorMap = new Map(); authorMap = new Map();
for (const authorRec of authorArr) { for (const authorRec of authorArr) {
authorRec.id = ++id; authorRec.id = ++id;
@@ -126,7 +122,6 @@ class DbCreator {
} }
utils.freeMemory(); utils.freeMemory();
await db.freeMemory();
//теперь можно создавать остальные поисковые таблицы //теперь можно создавать остальные поисковые таблицы
const parseField = (fieldValue, fieldMap, fieldArr, authorIds) => { const parseField = (fieldValue, fieldMap, fieldArr, authorIds) => {
@@ -169,10 +164,8 @@ class DbCreator {
parseField(rec.title, titleMap, titleArr, authorIds); parseField(rec.title, titleMap, titleArr, authorIds);
//жанры //жанры
if (!rec.genre) let genre = rec.genre || emptyFieldValue;
rec.genre = emptyFieldValue; genre = rec.genre.split(',');
const genre = rec.genre.split(',');
for (const g of genre) { for (const g of genre) {
let genreRec; let genreRec;
@@ -192,42 +185,57 @@ class DbCreator {
//языки //языки
parseField(rec.lang, langMap, langArr, authorIds); parseField(rec.lang, langMap, langArr, authorIds);
} };
callback({job: 'search tables create', jobMessage: 'Создание поисковых таблиц'}); const parseBookChunk = async(authorChunk) => {
const abRows = [];
//парсинг 2 for (const a of authorChunk) {
while (1) {// eslint-disable-line const aBooks = [];
//пробегаемся по сохраненным книгам for (const id of a.bookId) {
const rows = await db.select({ const rec = bookArr[id];
table: 'book',
where: `
let iter = @getItem('book_parsing');
if (!iter) {
iter = @all();
@setItem('book_parsing', iter);
}
const ids = new Set();
let id = iter.next();
while (!id.done && ids.size < 10000) {
ids.add(id.value);
id = iter.next();
}
return ids;
`
});
if (rows.length) {
for (const rec of rows)
parseBookRec(rec); parseBookRec(rec);
} else { aBooks.push(rec);
break; }
abRows.push({id: a.id, author: a.author, books: JSON.stringify(aBooks)});
delete a.bookId;//в дальнейшем не понадобится, authorArr сохраняем без него
} }
await db.insert({
table: 'author_book',
rows: abRows,
});
};
callback({job: 'search tables create', jobMessage: 'Создание поисковых таблиц'});
//парсинг 2, заполнение посиковых таблиц, сохранение author_book
await db.create({
table: 'author_book',
});
let idsLen = 0;
let aChunk = [];
for (const author of authorArr) {// eslint-disable-line
aChunk.push(author);
idsLen += author.bookId.length;
if (idsLen > 50000) {
await parseBookChunk(aChunk);
idsLen = 0;
aChunk = [];
utils.freeMemory();
await db.freeMemory();
}
}
if (aChunk.length) {
await parseBookChunk(aChunk);
aChunk = null;
} }
//чистка памяти, ибо жрет как не в себя //чистка памяти, ибо жрет как не в себя
bookArr = null;
authorMap = null; authorMap = null;
seriesMap = null; seriesMap = null;
titleMap = null; titleMap = null;
@@ -297,23 +305,23 @@ class DbCreator {
}; };
//author //author
callback({job: 'author save', jobMessage: 'Сохранение авторов книг'}); callback({job: 'author save', jobMessage: 'Сохранение индекса авторов'});
await saveTable('author', authorArr, () => {authorArr = null}, false); await saveTable('author', authorArr, () => {authorArr = null}, false);
//series //series
callback({job: 'series save', jobMessage: 'Сохранение серий книг'}); callback({job: 'series save', jobMessage: 'Сохранение индекса серий'});
await saveTable('series', seriesArr, () => {seriesArr = null}); await saveTable('series', seriesArr, () => {seriesArr = null});
//title //title
callback({job: 'title save', jobMessage: 'Сохранение названий книг'}); callback({job: 'title save', jobMessage: 'Сохранение индекса названий'});
await saveTable('title', titleArr, () => {titleArr = null}); await saveTable('title', titleArr, () => {titleArr = null});
//genre //genre
callback({job: 'genre save', jobMessage: 'Сохранение жанров'}); callback({job: 'genre save', jobMessage: 'Сохранение индекса жанров'});
await saveTable('genre', genreArr, () => {genreArr = null}); await saveTable('genre', genreArr, () => {genreArr = null});
//lang //lang
callback({job: 'lang save', jobMessage: 'Сохранение языков'}); callback({job: 'lang save', jobMessage: 'Сохранение индекса языков'});
await saveTable('lang', langArr, () => {langArr = null}); await saveTable('lang', langArr, () => {langArr = null});
//кэш-таблицы запросов //кэш-таблицы запросов

View File

@@ -289,8 +289,7 @@ class DbSearcher {
//выборка автора по authorId //выборка автора по authorId
const rows = await db.select({ const rows = await db.select({
table: 'author', table: 'author_book',
map: `(r) => ({author: r.author, bookId: r.bookId})`,
where: `@@id(${db.esc(authorId)})` where: `@@id(${db.esc(authorId)})`
}); });
@@ -299,13 +298,7 @@ class DbSearcher {
if (rows.length) { if (rows.length) {
author = rows[0].author; author = rows[0].author;
books = rows[0].books;
//выборка книг по bookId
books = await db.select({
table: 'book',
//map: `(r) => ({})`,
where: `@@id(${db.esc(rows[0].bookId)})`,
});
} }
result = {author, books}; result = {author, books};