{ "name": "Project Vectorization", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "minutes", "minutesInterval": 5 } ] } }, "id": "cron-node", "name": "Cron", "type": "n8n-nodes-base.cron", "typeVersion": 1.2, "position": [250, 300] }, { "parameters": { "operation": "executeQuery", "query": "SELECT id, name, \"nameEn\", description, \"descriptionEn\", content, \"contentEn\"\nFROM \"projects\"\nWHERE \"embedding\" IS NULL\n AND \"status\" = 'ACTIVE'\nLIMIT 20", "options": {} }, "id": "postgres-query", "name": "查询未向量化项目", "type": "n8n-nodes-base.postgres", "typeVersion": 2.5, "position": [470, 300], "credentials": { "postgres": { "id": "NEON_DATABASE_CREDENTIAL_ID", "name": "Neon Database" } } }, { "parameters": { "jsCode": "// 为每个项目构造用于向量化的文本内容\nconst projects = $input.all();\n\nreturn projects.map(item => {\n const project = item.json;\n\n // 合并字段,按权重构造\n const parts = [\n project.name || '',\n project.nameEn || '',\n project.description || '',\n project.descriptionEn || '',\n (project.content || '').substring(0, 500),\n (project.contentEn || '').substring(0, 500)\n ].filter(Boolean);\n\n const textContent = parts.join('\\n\\n');\n\n return {\n json: {\n ...project,\n textContent: textContent\n }\n };\n});" }, "id": "construct-content", "name": "构造文本内容", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [690, 300] }, { "parameters": { "batchSize": 5, "options": {} }, "id": "split-batches", "name": "Split in Batches", "type": "n8n-nodes-base.splitInBatches", "typeVersion": 3, "position": [910, 300] }, { "parameters": { "resource": "embedding", "model": "text-embedding-3-small", "input": "={{ $json.textContent }}", "options": {} }, "id": "openai-embeddings", "name": "OpenAI Embeddings", "type": "@n8n/n8n-nodes-langchain.openai", "typeVersion": 1.4, "position": [1130, 300], "credentials": { "openaiApi": { "id": "OPENAI_CREDENTIAL_ID", "name": "OpenAI Embeddings" } } }, { "parameters": { "operation": "executeQuery", "query": "=UPDATE \"projects\"\nSET\n \"embedding\" = '{{ $json.data[0].embedding }}'::vector,\n \"embeddingUpdatedAt\" = NOW()\nWHERE \"id\" = {{ $json.id }}", "options": {} }, "id": "postgres-update", "name": "更新 Embedding", "type": "n8n-nodes-base.postgres", "typeVersion": 2.5, "position": [1350, 300], "credentials": { "postgres": { "id": "NEON_DATABASE_CREDENTIAL_ID", "name": "Neon Database" } } } ], "connections": { "Cron": { "main": [ [ { "node": "查询未向量化项目", "type": "main", "index": 0 } ] ] }, "查询未向量化项目": { "main": [ [ { "node": "构造文本内容", "type": "main", "index": 0 } ] ] }, "构造文本内容": { "main": [ [ { "node": "Split in Batches", "type": "main", "index": 0 } ] ] }, "Split in Batches": { "main": [ [ { "node": "OpenAI Embeddings", "type": "main", "index": 0 } ] ] }, "OpenAI Embeddings": { "main": [ [ { "node": "更新 Embedding", "type": "main", "index": 0 } ] ] }, "更新 Embedding": { "main": [ [ { "node": "Split in Batches", "type": "main", "index": 0 } ] ] } }, "pinData": {}, "settings": { "executionOrder": "v1" }, "staticData": null, "tags": [], "triggerCount": 0, "updatedAt": "2026-01-26T00:00:00.000Z", "versionId": "1" }