update search command to use FTS5 SQLite table for complex searches
This commit is contained in:
parent
d839089153
commit
167829704a
8 changed files with 1359 additions and 267 deletions
|
@ -1,14 +1,15 @@
|
|||
/**
|
||||
* sigma_search_service.js
|
||||
*
|
||||
* This service provides functionality for searching Sigma rules by keywords.
|
||||
* This service provides functionality for searching Sigma rules by keywords and complex queries.
|
||||
* It processes search results and returns them in a structured format.
|
||||
* Supports pagination for large result sets.
|
||||
*/
|
||||
const { searchRules } = require('../../sigma_db/sigma_db_queries');
|
||||
|
||||
const { searchRules, searchRulesComplex } = require('../../sigma_db/sigma_db_queries');
|
||||
const { parseComplexQuery } = require('../../lang/query_parser');
|
||||
const logger = require('../../utils/logger');
|
||||
const { convertSigmaRule } = require('./sigma_converter_service');
|
||||
|
||||
const { getFileName } = require('../../utils/file_utils');
|
||||
const FILE_NAME = getFileName(__filename);
|
||||
|
||||
|
@ -153,6 +154,109 @@ async function searchSigmaRules(keyword, page = 1, pageSize = 10) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for Sigma rules using complex query conditions
|
||||
* Supports filtering by title, logsource, tags, dates, and more
|
||||
*
|
||||
* @param {string} queryString - The complex query string to parse
|
||||
* @param {number} page - Page number (1-based index, default: 1)
|
||||
* @param {number} pageSize - Number of results per page (default: 10)
|
||||
* @returns {Promise<Object>} Result object with success flag and processed results
|
||||
*/
|
||||
async function searchSigmaRulesComplex(queryString, page = 1, pageSize = 10) {
|
||||
if (!queryString || typeof queryString !== 'string') {
|
||||
logger.warn(`${FILE_NAME}: Cannot perform complex search: Missing or invalid query string`);
|
||||
return {
|
||||
success: false,
|
||||
message: 'Missing or invalid complex query'
|
||||
};
|
||||
}
|
||||
|
||||
// Validate pagination parameters
|
||||
if (typeof page !== 'number' || page < 1) {
|
||||
logger.warn(`${FILE_NAME}: Invalid page number: ${page}, defaulting to 1`);
|
||||
page = 1;
|
||||
}
|
||||
|
||||
if (typeof pageSize !== 'number' || pageSize < 1 || pageSize > 100) {
|
||||
logger.warn(`${FILE_NAME}: Invalid page size: ${pageSize}, defaulting to 10`);
|
||||
pageSize = 10;
|
||||
}
|
||||
|
||||
// Calculate the offset based on page number
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
logger.info(`${FILE_NAME}: Performing complex search with query: "${queryString}" (page ${page}, size ${pageSize})`);
|
||||
|
||||
try {
|
||||
// Parse the complex query string
|
||||
const parsedQuery = parseComplexQuery(queryString);
|
||||
|
||||
if (!parsedQuery.valid) {
|
||||
logger.warn(`${FILE_NAME}: Invalid complex query: ${parsedQuery.error}`);
|
||||
return {
|
||||
success: false,
|
||||
message: `Invalid query: ${parsedQuery.error}`
|
||||
};
|
||||
}
|
||||
|
||||
// Perform the database search with the parsed query
|
||||
const searchResult = await searchRulesComplex(parsedQuery, pageSize, offset);
|
||||
|
||||
// Defensive handling of possible return formats
|
||||
let allResults = [];
|
||||
let totalCount = 0;
|
||||
|
||||
// Handle search results
|
||||
if (searchResult) {
|
||||
if (Array.isArray(searchResult.results)) {
|
||||
allResults = searchResult.results;
|
||||
totalCount = searchResult.totalCount || 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (allResults.length === 0) {
|
||||
return {
|
||||
success: true,
|
||||
results: [],
|
||||
message: `No rules found matching the complex query criteria`,
|
||||
pagination: {
|
||||
currentPage: page,
|
||||
pageSize: pageSize,
|
||||
totalPages: Math.ceil(totalCount / pageSize),
|
||||
totalResults: totalCount,
|
||||
hasMore: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Calculate pagination info
|
||||
const totalPages = Math.ceil(totalCount / pageSize);
|
||||
const hasMore = (offset + pageSize) < totalCount;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
results: allResults,
|
||||
count: allResults.length,
|
||||
query: parsedQuery,
|
||||
pagination: {
|
||||
currentPage: page,
|
||||
pageSize: pageSize,
|
||||
totalPages: totalPages,
|
||||
totalResults: totalCount,
|
||||
hasMore: hasMore
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`${FILE_NAME}: Error in complex search: ${error.message}`);
|
||||
logger.debug(`${FILE_NAME}: Error stack: ${error.stack}`);
|
||||
return {
|
||||
success: false,
|
||||
message: `Error performing complex search: ${error.message}`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced search that returns fully converted rule objects with pagination support
|
||||
* This is a more expensive operation than basic search
|
||||
|
@ -210,5 +314,6 @@ async function searchAndConvertRules(keyword, page = 1, pageSize = 10) {
|
|||
|
||||
module.exports = {
|
||||
searchSigmaRules,
|
||||
searchSigmaRulesComplex,
|
||||
searchAndConvertRules
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue