Elasticsearch 기반 동적 검색 인터페이스와 자동화된 보고서 생성
중급
이것은Document Extraction, Multimodal AI분야의자동화 워크플로우로, 11개의 노드를 포함합니다.주로 Code, FormTrigger, HttpRequest, ReadWriteFile 등의 노드를 사용하며. Elasticsearch의 동적 검색 인터페이스와 자동 보고서 생성 사용
사전 요구사항
- •대상 API의 인증 정보가 필요할 수 있음
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"id": "3eqTGbhtSxDjuMZC",
"meta": {
"instanceId": "5cee0adb1ef2b84ac8a86937fac5115d710898b6c70f9f7c3f3ca3ef70a11bf7",
"templateCredsSetupCompleted": true
},
"name": "Dynamic Search Interface with Elasticsearch and Automated Report Generation",
"tags": [],
"nodes": [
{
"id": "e3eb30ef-51d9-4cd5-ab1f-807b87e06795",
"name": "검색 양식",
"type": "n8n-nodes-base.formTrigger",
"position": [
480,
-220
],
"webhookId": "169f8e1c-e4a8-4229-9b2a-9db33003f221",
"parameters": {
"path": "169f8e1c-e4a8-4229-9b2a-9db33003f221",
"options": {},
"formTitle": "🔍 Dynamic Search",
"formFields": {
"values": [
{
"fieldType": "number",
"fieldLabel": "Minimum Amount ($)"
},
{
"fieldType": "dropdown",
"fieldLabel": "Time Range",
"fieldOptions": {
"values": [
{
"option": "Last 1 Hour"
},
{
"option": "Last 6 Hours"
},
{
"option": "Last 24 Hours"
},
{
"option": "Last 3 Days"
}
]
},
"requiredField": true
},
{
"fieldLabel": "Customer ID (Optional)"
},
{
"fieldType": "dropdown",
"fieldLabel": "Report Format",
"fieldOptions": {
"values": [
{
"option": "Text Report"
},
{
"option": "CSV Export"
}
]
},
"requiredField": true
}
]
},
"responseMode": "responseNode",
"formDescription": "Search for suspicious transactions in your banking database"
},
"typeVersion": 2.1
},
{
"id": "79e2a04d-9427-4d8d-ae8a-41005a2ab80d",
"name": "검색 쿼리 작성",
"type": "n8n-nodes-base.code",
"position": [
700,
-220
],
"parameters": {
"jsCode": "// Process form input and build Elasticsearch query\nconst formData = $input.first().json;\n\n// Extract form values\nconst minAmount = formData['Minimum Amount ($)'] || 1000;\nconst timeRange = formData['Time Range'] || 'Last 24 Hours';\nconst customerId = formData['Customer ID (Optional)']?.trim() || null;\nconst reportFormat = formData['Report Format'] || 'Text Report';\n\n// Convert time range to Elasticsearch format\nlet timeRangeES;\nswitch(timeRange) {\n case 'Last 1 Hour':\n timeRangeES = 'now-1h';\n break;\n case 'Last 6 Hours':\n timeRangeES = 'now-6h';\n break;\n case 'Last 24 Hours':\n timeRangeES = 'now-24h';\n break;\n case 'Last 3 Days':\n timeRangeES = 'now-3d';\n break;\n default:\n timeRangeES = 'now-24h';\n}\n\n// Build Elasticsearch query\nconst mustConditions = [\n {\n \"range\": {\n \"timestamp\": {\n \"gte\": timeRangeES\n }\n }\n },\n {\n \"range\": {\n \"amount\": {\n \"gte\": minAmount\n }\n }\n }\n];\n\n// Add customer filter if provided\nif (customerId) {\n mustConditions.push({\n \"term\": {\n \"customer_id.keyword\": customerId\n }\n });\n}\n\nconst esQuery = {\n \"query\": {\n \"bool\": {\n \"must\": mustConditions\n }\n },\n \"sort\": [{ \"timestamp\": { \"order\": \"desc\" } }],\n \"size\": 100\n};\n\nreturn {\n elasticsearchQuery: esQuery,\n searchParams: {\n minAmount,\n timeRange,\n customerId,\n reportFormat\n }\n};"
},
"typeVersion": 2
},
{
"id": "62e186d7-c90f-4576-8c56-d850e784e9e0",
"name": "Elasticsearch 검색",
"type": "n8n-nodes-base.httpRequest",
"position": [
940,
-220
],
"parameters": {
"url": "https://localhost:9220/bank_transactions/_search",
"options": {
"allowUnauthorizedCerts": true
},
"jsonBody": "={{ $json.elasticsearchQuery }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"typeVersion": 4.1
},
{
"id": "4869c996-8a2e-40a1-aea3-384e0e379c14",
"name": "보고서 서식 지정",
"type": "n8n-nodes-base.code",
"position": [
1140,
-220
],
"parameters": {
"jsCode": "// Get data from previous nodes\nconst esResponse = $input.first().json;\nconst searchParams = $('Build Search Query').first().json.searchParams;\n\n// Extract results\nconst hits = esResponse.hits?.hits || [];\nconst totalFound = esResponse.hits?.total?.value || 0;\n\n// Generate filename\nconst timestamp = new Date().toISOString().split('T')[0];\nconst isCSV = searchParams.reportFormat === 'CSV Export';\nconst filename = `report_${timestamp}.${isCSV ? 'csv' : 'txt'}`;\nconst mimeType = isCSV ? 'text/csv' : 'text/plain';\n\n// Generate report content\nlet reportContent = '';\n\nif (isCSV) {\n // CSV format\n reportContent = 'Transaction_ID,Customer_ID,Amount,Merchant_Category,Timestamp\\n';\n hits.forEach(hit => {\n const t = hit._source || {};\n reportContent += `\"${t.transaction_id || ''}\",\"${t.customer_id || ''}\",${t.amount || 0},\"${t.merchant_category || ''}\",\"${t.timestamp || ''}\"\\n`;\n });\n} else {\n // Text format\n reportContent = `DYNAMIC SEARCH REPORT\\n`;\n reportContent += `======================\\n\\n`;\n reportContent += `Search Criteria:\\n`;\n reportContent += `- Minimum Amount: $${searchParams.minAmount}\\n`;\n reportContent += `- Time Range: ${searchParams.timeRange}\\n`;\n reportContent += `- Customer: ${searchParams.customerId || 'All'}\\n\\n`;\n reportContent += `Results: ${totalFound} transactions found\\n\\n`;\n \n if (hits.length > 0) {\n reportContent += `TRANSACTIONS:\\n`;\n reportContent += `=============\\n\\n`;\n hits.forEach((hit, index) => {\n const t = hit._source || {};\n reportContent += `${index + 1}. Transaction ID: ${t.transaction_id}\\n`;\n reportContent += ` Customer: ${t.customer_id}\\n`;\n reportContent += ` Amount: $${t.amount}\\n`;\n reportContent += ` Merchant: ${t.merchant_category}\\n`;\n reportContent += ` Time: ${t.timestamp}\\n\\n`;\n });\n } else {\n reportContent += `No suspicious transactions found matching your criteria.\\n`;\n }\n}\n\n// Convert content to binary data\nconst binaryData = Buffer.from(reportContent, 'utf8');\n\nreturn {\n json: {\n filename: filename,\n mimeType: mimeType,\n content: reportContent\n },\n binary: {\n data: binaryData\n }\n};"
},
"typeVersion": 2
},
{
"id": "764ac1c5-0ae2-4048-884b-dceb4ea6d719",
"name": "디스크에서 파일 읽기/쓰기",
"type": "n8n-nodes-base.readWriteFile",
"position": [
1320,
-220
],
"parameters": {
"options": {},
"fileName": "=/tmp/{{ $json.filename }}",
"operation": "write"
},
"typeVersion": 1
},
{
"id": "b4c9ae5c-cd17-492e-a543-205329a872b9",
"name": "스티커 노트",
"type": "n8n-nodes-base.stickyNote",
"position": [
40,
-260
],
"parameters": {
"width": 360,
"height": 220,
"content": "## 🎯 ENTRY POINT\nUser fills out dynamic search form with:\n- Minimum transaction amount\n- Time range (1hr to 3 days)\n- Optional customer ID filter\n- Output format (Text/CSV)\n\n💡 TIP: Form auto-validates required fields!"
},
"typeVersion": 1
},
{
"id": "b36fea54-e177-4edc-a091-110b25475ad4",
"name": "스티커 노트1",
"type": "n8n-nodes-base.stickyNote",
"position": [
40,
0
],
"parameters": {
"color": 2,
"width": 360,
"height": 300,
"content": "## 🔧 QUERY BUILDER\nTransforms user input into Elasticsearch query:\n\n✅ Converts time ranges:\n \"Last 24 Hours\" → \"now-24h\"\n \"Last 3 Days\" → \"now-3d\"\n\n✅ Builds filters:\n • Amount >= minimum\n • Timestamp within range\n • Customer ID (if provided)\n\n📊 Output: Ready-to-use ES query + metadata"
},
"typeVersion": 1
},
{
"id": "8d3f38d7-b483-43cb-bcb5-9524a7a17e86",
"name": "스티커 노트2",
"type": "n8n-nodes-base.stickyNote",
"position": [
440,
0
],
"parameters": {
"color": 3,
"width": 320,
"height": 260,
"content": "## 🎯 DATA HUNTER\nSearches bank_transactions index for suspicious activity\n\n🔧 Configuration:\n • POST to localhost:9220\n • Uses HTTP Basic Auth\n • Sends JSON query from previous node\n • Returns max 100 results, newest first\n\n⚠️ Note: Requires valid ES credentials!"
},
"typeVersion": 1
},
{
"id": "11039177-def0-4de1-ad25-f91e1294abee",
"name": "스티커 노트3",
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
0
],
"parameters": {
"color": 4,
"width": 340,
"height": 340,
"content": "## 📝 REPORT GENERATOR\nTransforms raw ES data into user-friendly reports\n\n🎨 Creates two formats:\n 📄 TEXT: Human-readable summary\n 📊 CSV: Spreadsheet-ready data export\n\n✨ Features:\n • Auto-generates timestamped filename\n • Converts text to binary for file writing\n • Includes search criteria summary\n • Lists all suspicious transactions\n\n🔄 Output: Content + Binary data ready for file save"
},
"typeVersion": 1
},
{
"id": "7c8c7226-a9e3-4edb-9497-e1980f3e84ea",
"name": "스티커 노트4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1180,
0
],
"parameters": {
"color": 5,
"width": 400,
"height": 260,
"content": "## 📁 FILE SAVER\nWrites the report to server disk\n\n📍 Location: /tmp/report_YYYY-MM-DD.{txt|csv}\n🔧 Uses binary data from Format Report node\n✅ File ready for download or further processing\n\n🎯 Perfect for:\n • Audit trails\n • Batch processing\n • Compliance reporting"
},
"typeVersion": 1
},
{
"id": "79d96536-a117-474b-a524-ec0e54f7ae2b",
"name": "스티커 노트5",
"type": "n8n-nodes-base.stickyNote",
"position": [
40,
-520
],
"parameters": {
"color": 6,
"width": 720,
"height": 200,
"content": "## 🎯 DYNAMIC SEARCH PIPELINE\n\nUser Form → Query Builder → ES Search → Report Format → File Save\n\n⏱️ Typical execution: 2-5 seconds\n📊 Handles up to 100 suspicious transactions\n🔒 Secure: Uses authenticated ES connection\n📁 Output: Timestamped report files in /tmp/"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "42705d97-c55a-4ebe-8107-536a8c7faea3",
"connections": {
"e3eb30ef-51d9-4cd5-ab1f-807b87e06795": {
"main": [
[
{
"node": "79e2a04d-9427-4d8d-ae8a-41005a2ab80d",
"type": "main",
"index": 0
}
]
]
},
"4869c996-8a2e-40a1-aea3-384e0e379c14": {
"main": [
[
{
"node": "764ac1c5-0ae2-4048-884b-dceb4ea6d719",
"type": "main",
"index": 0
}
]
]
},
"79e2a04d-9427-4d8d-ae8a-41005a2ab80d": {
"main": [
[
{
"node": "62e186d7-c90f-4576-8c56-d850e784e9e0",
"type": "main",
"index": 0
}
]
]
},
"62e186d7-c90f-4576-8c56-d850e784e9e0": {
"main": [
[
{
"node": "4869c996-8a2e-40a1-aea3-384e0e379c14",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
중급 - 문서 추출, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
항공편 분석 복사본
Chart.js, QuickChart API, Telegram 로봇을 사용하여 항공 데이터를 시각화
If
Code
Switch
+
If
Code
Switch
24 노드DataMinex
시장 조사
PDF에서 주문으로
AI를 사용한 PDF 구매 주문서를 Adobe Commerce 판매 주문서로 자동 변환
If
Set
Code
+
If
Set
Code
96 노드JKingma
문서 추출
연구 계획
Gemini AI, Google Docs 및 인간 피드백을 사용한 UX 연구 계획 자동화
Code
Gmail
Google Docs
+
Code
Gmail
Google Docs
33 노드Zeinabsadat Mousavi Amin
문서 추출
GST Insights API와 Google Docs를 사용하여 자동화된 GST 보고서 생성
GST Insights API와 Google Docs를 사용하여 자동화된 GST 보고서 생성
Code
Google Docs
Form Trigger
+
Code
Google Docs
Form Trigger
9 노드Evoort Solutions
문서 추출
전자책을 오디오북으로 변환
MiniMax와 FFmpeg를 사용하여 전자책을 오디오북으로 변환
Code
Wait
Form Trigger
+
Code
Wait
Form Trigger
19 노드Jay Emp0
콘텐츠 제작
GPT-4o Vision과 Telegram 이미지 분석 및 텍스트 추출
GPT-4o Vision과 Telegram을 사용한 이미지 분석 및 텍스트 추출
Code
Telegram
Http Request
+
Code
Telegram
Http Request
16 노드AI/ML API | D1m7asis
문서 추출