n8n-nodes-fuse-postgre-master
Version:
Node do n8n para buscas fuzzy no PostgreSQL usando Fuse.js.
191 lines (190 loc) • 7.96 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FusePostgre = void 0;
const pg_1 = require("pg");
const fuse_js_1 = __importDefault(require("fuse.js"));
class FusePostgre {
constructor() {
this.description = {
displayName: 'Fuse Postgre',
name: 'fusePostgre',
icon: 'fa:search',
group: ['transform'],
version: 1,
description: 'Busca fuzzy no PostgreSQL usando Fuse.js',
defaults: {
name: 'Fuse Postgre',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'postgres',
required: true,
},
],
properties: [
{
displayName: 'Tabela',
name: 'table',
type: 'string',
default: '',
placeholder: 'nome_da_tabela',
description: 'Nome da tabela para buscar',
required: true,
},
{
displayName: 'Campo de Busca',
name: 'searchField',
type: 'string',
default: '',
placeholder: 'nome, email, descricao',
description: 'Campo(s) para realizar a busca (separados por vírgula)',
required: true,
},
{
displayName: 'Termo de Busca',
name: 'searchTerm',
type: 'string',
default: '',
placeholder: 'termo para buscar',
description: 'Termo que será buscado usando Fuse.js',
required: true,
},
{
displayName: 'Limite de Resultados',
name: 'limit',
type: 'number',
default: 10,
description: 'Número máximo de resultados a retornar',
},
{
displayName: 'Configurações do Fuse.js',
name: 'fuseOptions',
type: 'collection',
default: {},
options: [
{
displayName: 'Threshold',
name: 'threshold',
type: 'number',
default: 0.6,
description: 'Limite de similaridade (0 = perfeita, 1 = qualquer coisa)',
typeOptions: {
minValue: 0,
maxValue: 1,
numberStepSize: 0.1,
},
},
{
displayName: 'Distance',
name: 'distance',
type: 'number',
default: 100,
description: 'Distância máxima entre caracteres para considerar uma correspondência',
},
{
displayName: 'MinMatchCharLength',
name: 'minMatchCharLength',
type: 'number',
default: 1,
description: 'Comprimento mínimo de caracteres que devem corresponder',
},
{
displayName: 'IsCaseSensitive',
name: 'isCaseSensitive',
type: 'boolean',
default: false,
description: 'Se a busca deve ser sensível a maiúsculas/minúsculas',
},
],
},
{
displayName: 'Condições WHERE',
name: 'whereConditions',
type: 'string',
default: '',
placeholder: "status = 'ativo' AND created_at > '2023-01-01'",
description: 'Condições SQL adicionais para filtrar os dados (opcional)',
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
for (let i = 0; i < items.length; i++) {
try {
const table = this.getNodeParameter('table', i);
const searchField = this.getNodeParameter('searchField', i);
const searchTerm = this.getNodeParameter('searchTerm', i);
const limit = this.getNodeParameter('limit', i);
const fuseOptions = this.getNodeParameter('fuseOptions', i);
const whereConditions = this.getNodeParameter('whereConditions', i);
// Obter credenciais do PostgreSQL
const credentials = await this.getCredentials('postgres');
const client = new pg_1.Client({
host: credentials.host,
port: credentials.port,
database: credentials.database,
user: credentials.user,
password: credentials.password,
ssl: credentials.ssl ? { rejectUnauthorized: false } : false,
});
await client.connect();
// Construir query SQL
let query = `SELECT * FROM "${table}"`;
if (whereConditions) {
query += ` WHERE ${whereConditions}`;
}
// Executar query
const result = await client.query(query);
await client.end();
// Preparar dados para Fuse.js
const searchFields = searchField.split(',').map(field => field.trim());
const fuse = new fuse_js_1.default(result.rows, {
keys: searchFields,
threshold: fuseOptions.threshold || 0.6,
distance: fuseOptions.distance || 100,
minMatchCharLength: fuseOptions.minMatchCharLength || 1,
isCaseSensitive: fuseOptions.isCaseSensitive || false,
});
// Realizar busca fuzzy
const searchResults = fuse.search(searchTerm);
// Limitar resultados
const limitedResults = searchResults.slice(0, limit);
// Preparar dados de retorno
const returnItem = {
json: {
searchTerm,
totalResults: searchResults.length,
limitedResults: limitedResults.length,
results: limitedResults.map(result => ({
item: result.item,
score: result.score,
refIndex: result.refIndex,
})),
},
};
returnData.push(returnItem);
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error instanceof Error ? error.message : String(error),
},
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.FusePostgre = FusePostgre;
exports.default = FusePostgre;