add non-game content filter

This commit is contained in:
2025-03-17 02:48:34 -03:00
parent c5c680efea
commit e3ee89d663
5 changed files with 74 additions and 13 deletions

View File

@@ -18,6 +18,7 @@
"editor",
"emulator",
"expansion",
"figurine",
"firmware",
"guide",
"hack",
@@ -26,6 +27,7 @@
"installer",
"intro",
"json",
"jpg",
"manual",
"mod",
"movie",
@@ -44,6 +46,7 @@
"sdk",
"setup",
"soundtrack",
"sqlite",
"terms",
"tool",
"trainer",
@@ -51,7 +54,8 @@
"update",
"utility",
"video",
"Virtual Console",
"wallpaper"
"virtual console",
"wallpaper",
"xml"
]
}

View File

@@ -1,6 +1,9 @@
import { Client } from '@elastic/elasticsearch';
import debugPrint from '../debugprint.js';
import { File } from '../models/index.js';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
const client = new Client({
node: process.env.ELASTICSEARCH_URL || 'http://localhost:9200'
@@ -8,6 +11,23 @@ const client = new Client({
const INDEX_NAME = 'myrient_files';
// Cache for nonGameTerms
let nonGameTermsCache = null;
function getNonGameTerms() {
if (nonGameTermsCache) {
return nonGameTermsCache;
}
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const nonGameTermsPath = resolve(__dirname, '../../lib/nonGameTerms.json');
nonGameTermsCache = JSON.parse(readFileSync(nonGameTermsPath, 'utf8'));
return nonGameTermsCache;
}
export async function initElasticsearch() {
try {
const indexExists = await client.indices.exists({ index: INDEX_NAME });
@@ -111,7 +131,7 @@ export async function search(query, options) {
const searchQuery = {
index: INDEX_NAME,
body: {
size: 1000,
size: 1500,
query: {
bool: {
must: buildMustClauses(query, options),
@@ -132,7 +152,6 @@ export async function search(query, options) {
try {
const startTime = process.hrtime();
const response = await client.search(searchQuery);
const elapsed = parseHrtimeToSeconds(process.hrtime(startTime));
// Fetch full records from PostgreSQL for the search results
const ids = response.hits.hits.map(hit => hit._id);
@@ -146,13 +165,28 @@ export async function search(query, options) {
return map;
}, {});
// Combine Elasticsearch results with full PostgreSQL records
// Build results with full PostgreSQL records
let results = response.hits.hits.map(hit => ({
...recordMap[hit._id].dataValues,
score: hit._score,
highlights: hit.highlight
}));
// Apply non-game content filtering in JavaScript if the option is enabled
if (options.hideNonGame) {
const nonGameTerms = getNonGameTerms();
const termPatterns = nonGameTerms.terms.map(term => new RegExp(term, 'i'));
// Filter results in JavaScript (much faster than complex Elasticsearch queries)
results = results.filter(item => {
// Check if filename contains any of the non-game terms
return !termPatterns.some(pattern => pattern.test(item.filename));
});
}
const elapsed = parseHrtimeToSeconds(process.hrtime(startTime));
return {
items: response.hits.hits.map(hit => ({
...recordMap[hit._id].dataValues,
score: hit._score,
highlights: hit.highlight
})),
items: results,
elapsed
};
} catch (error) {