mirror of
https://github.com/NVIDIA/dgx-spark-playbooks.git
synced 2026-04-22 18:13:52 +00:00
feat: Add Neo4j support to txt2kg
Add Neo4j as an alternative graph database backend alongside ArangoDB. This includes updates to the frontend components, API routes, and docker-compose configuration for Neo4j integration.
This commit is contained in:
parent
6ef03c813f
commit
6105731e70
@ -7,7 +7,13 @@ services:
|
||||
ports:
|
||||
- '3001:3000'
|
||||
environment:
|
||||
- ARANGODB_URL=http://arangodb:8529
|
||||
# Neo4j configuration (ARM64 compatible - works with 64KB pages)
|
||||
- NEO4J_URI=bolt://neo4j:7687
|
||||
- NEO4J_USER=neo4j
|
||||
- NEO4J_PASSWORD=password123
|
||||
- GRAPH_DB_TYPE=neo4j
|
||||
# ArangoDB disabled - set to localhost to prevent DNS errors if accidentally accessed
|
||||
- ARANGODB_URL=http://localhost:8529
|
||||
- ARANGODB_DB=txt2kg
|
||||
- QDRANT_URL=http://qdrant:6333
|
||||
- VECTOR_DB_TYPE=qdrant
|
||||
@ -31,32 +37,47 @@ services:
|
||||
- txt2kg-network
|
||||
- pinecone-net
|
||||
depends_on:
|
||||
- arangodb
|
||||
- ollama
|
||||
neo4j:
|
||||
condition: service_healthy
|
||||
ollama:
|
||||
condition: service_started
|
||||
# Optional: sentence-transformers and entity-embeddings are only needed for vector search
|
||||
# Traditional graph search works without these services
|
||||
arangodb:
|
||||
image: arangodb:latest
|
||||
|
||||
# Neo4j - ARM64 compatible graph database (works with 64KB page size kernel)
|
||||
neo4j:
|
||||
image: neo4j:5-community
|
||||
ports:
|
||||
- '8529:8529'
|
||||
- '7474:7474' # HTTP
|
||||
- '7687:7687' # Bolt
|
||||
environment:
|
||||
- ARANGO_NO_AUTH=1
|
||||
- NEO4J_AUTH=neo4j/password123
|
||||
- NEO4J_server_memory_heap_initial__size=512m
|
||||
- NEO4J_server_memory_heap_max__size=2G
|
||||
volumes:
|
||||
- arangodb_data:/var/lib/arangodb3
|
||||
- arangodb_apps_data:/var/lib/arangodb3-apps
|
||||
arangodb-init:
|
||||
image: arangodb:latest
|
||||
depends_on:
|
||||
arangodb:
|
||||
condition: service_started
|
||||
restart: on-failure
|
||||
entrypoint: >
|
||||
sh -c "
|
||||
echo 'Waiting for ArangoDB to start...' &&
|
||||
sleep 10 &&
|
||||
echo 'Creating txt2kg database...' &&
|
||||
arangosh --server.endpoint tcp://arangodb:8529 --server.authentication false --javascript.execute-string 'try { db._createDatabase(\"txt2kg\"); console.log(\"Database txt2kg created successfully!\"); } catch(e) { if(e.message.includes(\"duplicate\")) { console.log(\"Database txt2kg already exists\"); } else { throw e; } }'
|
||||
"
|
||||
- neo4j_data:/data
|
||||
- neo4j_logs:/logs
|
||||
networks:
|
||||
- default
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:7474 || exit 1"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
start_period: 60s
|
||||
|
||||
# ArangoDB disabled - doesn't support ARM64 with 64KB page size
|
||||
# Uncomment if using 4KB page kernel (linux-nvidia-6.14)
|
||||
# arangodb:
|
||||
# image: arangodb:latest
|
||||
# ports:
|
||||
# - '8529:8529'
|
||||
# environment:
|
||||
# - ARANGO_NO_AUTH=1
|
||||
# volumes:
|
||||
# - arangodb_data:/var/lib/arangodb3
|
||||
# - arangodb_apps_data:/var/lib/arangodb3-apps
|
||||
ollama:
|
||||
build:
|
||||
context: ../services/ollama
|
||||
@ -70,11 +91,14 @@ services:
|
||||
environment:
|
||||
- NVIDIA_VISIBLE_DEVICES=all # Make all GPUs visible to the container
|
||||
- NVIDIA_DRIVER_CAPABILITIES=compute,utility # Required capabilities for CUDA
|
||||
- CUDA_VISIBLE_DEVICES=0 # Use first GPU
|
||||
- OLLAMA_FLASH_ATTENTION=1 # Enable flash attention for better performance
|
||||
- OLLAMA_KEEP_ALIVE=30m # Keep models loaded for 30 minutes
|
||||
- OLLAMA_NUM_PARALLEL=4 # Process 4 requests in parallel - DGX Spark has unified memory
|
||||
- OLLAMA_MAX_LOADED_MODELS=1 # Load only one model at a time to avoid VRAM contention
|
||||
- OLLAMA_KV_CACHE_TYPE=q8_0 # Reduce KV cache VRAM usage with minimal performance impact
|
||||
- OLLAMA_GPU_LAYERS=-1 # Force all layers on GPU
|
||||
- OLLAMA_LLM_LIBRARY=cuda # Force CUDA backend
|
||||
networks:
|
||||
- default
|
||||
restart: unless-stopped
|
||||
@ -161,10 +185,12 @@ services:
|
||||
- vector-search
|
||||
|
||||
volumes:
|
||||
arangodb_data:
|
||||
arangodb_apps_data:
|
||||
neo4j_data:
|
||||
neo4j_logs:
|
||||
ollama_data:
|
||||
qdrant_data:
|
||||
# arangodb_data:
|
||||
# arangodb_apps_data:
|
||||
|
||||
networks:
|
||||
default:
|
||||
|
||||
@ -88,13 +88,18 @@ async function ensureConnection(request?: NextRequest): Promise<GraphDBType> {
|
||||
* GET handler for retrieving graph data from the selected graph database
|
||||
*/
|
||||
export async function GET(request: NextRequest) {
|
||||
console.log('[graph-db GET] Request received');
|
||||
try {
|
||||
// Initialize with connection parameters
|
||||
console.log('[graph-db GET] Ensuring connection...');
|
||||
const graphDbType = await ensureConnection(request);
|
||||
console.log(`[graph-db GET] Using database type: ${graphDbType}`);
|
||||
const graphDbService = getGraphDbService(graphDbType);
|
||||
|
||||
// Get graph data from the database
|
||||
console.log('[graph-db GET] Fetching graph data...');
|
||||
const graphData = await graphDbService.getGraphData();
|
||||
console.log(`[graph-db GET] Got ${graphData.nodes.length} nodes, ${graphData.relationships.length} relationships`);
|
||||
|
||||
// Transform to format expected by the frontend
|
||||
const nodes = graphData.nodes.map(node => ({
|
||||
|
||||
@ -17,8 +17,26 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { GraphDBType } from '@/lib/graph-db-service';
|
||||
|
||||
// In-memory storage for settings
|
||||
// In-memory storage for settings - use lazy initialization for env vars
|
||||
// because they're not available at build time, only at runtime
|
||||
let serverSettings: Record<string, string> = {};
|
||||
let settingsInitialized = false;
|
||||
|
||||
function ensureSettingsInitialized() {
|
||||
if (!settingsInitialized) {
|
||||
// Read environment variables at runtime, not build time
|
||||
serverSettings = {
|
||||
graph_db_type: process.env.GRAPH_DB_TYPE || 'arangodb',
|
||||
neo4j_uri: process.env.NEO4J_URI || '',
|
||||
neo4j_user: process.env.NEO4J_USER || process.env.NEO4J_USERNAME || '',
|
||||
neo4j_password: process.env.NEO4J_PASSWORD || '',
|
||||
arangodb_url: process.env.ARANGODB_URL || '',
|
||||
arangodb_db: process.env.ARANGODB_DB || '',
|
||||
};
|
||||
settingsInitialized = true;
|
||||
console.log(`[SETTINGS] Initialized at runtime with GRAPH_DB_TYPE: "${serverSettings.graph_db_type}"`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API Route to sync client settings with server environment variables
|
||||
@ -27,13 +45,16 @@ let serverSettings: Record<string, string> = {};
|
||||
*/
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
// Ensure settings are initialized from env vars first
|
||||
ensureSettingsInitialized();
|
||||
|
||||
const { settings } = await request.json();
|
||||
|
||||
if (!settings || typeof settings !== 'object') {
|
||||
return NextResponse.json({ error: 'Settings object is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Update server settings
|
||||
// Update server settings (merge with existing)
|
||||
serverSettings = { ...serverSettings, ...settings };
|
||||
|
||||
// Log some important settings for debugging
|
||||
@ -58,6 +79,9 @@ export async function POST(request: NextRequest) {
|
||||
*/
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
// Ensure settings are initialized from env vars first
|
||||
ensureSettingsInitialized();
|
||||
|
||||
const url = new URL(request.url);
|
||||
const key = url.searchParams.get('key');
|
||||
|
||||
@ -84,12 +108,32 @@ export async function GET(request: NextRequest) {
|
||||
* For use in other API routes
|
||||
*/
|
||||
export function getSetting(key: string): string | null {
|
||||
ensureSettingsInitialized();
|
||||
return serverSettings[key] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently selected graph database type
|
||||
* Priority: serverSettings > environment variable > default 'arangodb'
|
||||
*/
|
||||
export function getGraphDbType(): GraphDBType {
|
||||
return (serverSettings.graph_db_type as GraphDBType) || 'arangodb';
|
||||
// Ensure settings are initialized from runtime environment variables
|
||||
ensureSettingsInitialized();
|
||||
|
||||
// Check serverSettings (initialized from env vars or updated by client)
|
||||
if (serverSettings.graph_db_type) {
|
||||
console.log(`[getGraphDbType] Returning: "${serverSettings.graph_db_type}"`);
|
||||
return serverSettings.graph_db_type as GraphDBType;
|
||||
}
|
||||
|
||||
// Direct fallback to runtime environment variable
|
||||
const envType = process.env.GRAPH_DB_TYPE;
|
||||
if (envType) {
|
||||
console.log(`[getGraphDbType] Returning from env: "${envType}"`);
|
||||
return envType as GraphDBType;
|
||||
}
|
||||
|
||||
// Default to arangodb for backwards compatibility
|
||||
console.log(`[getGraphDbType] Returning default: "arangodb"`);
|
||||
return 'arangodb';
|
||||
}
|
||||
@ -57,24 +57,34 @@ export function DatabaseConnection({ className }: DatabaseConnectionProps) {
|
||||
setGraphError(null)
|
||||
|
||||
try {
|
||||
// Get database type from localStorage
|
||||
const graphDbType = localStorage.getItem("graph_db_type") || "arangodb"
|
||||
// Get database type from localStorage, fall back to fetching from server
|
||||
let graphDbType = localStorage.getItem("graph_db_type")
|
||||
if (!graphDbType) {
|
||||
// Fetch server's default (from GRAPH_DB_TYPE env var)
|
||||
try {
|
||||
const settingsRes = await fetch('/api/settings')
|
||||
const settingsData = await settingsRes.json()
|
||||
graphDbType = settingsData.settings?.graph_db_type || 'neo4j'
|
||||
} catch {
|
||||
graphDbType = 'neo4j'
|
||||
}
|
||||
}
|
||||
setDbType(graphDbType === "arangodb" ? "ArangoDB" : "Neo4j")
|
||||
|
||||
if (graphDbType === "neo4j") {
|
||||
// Neo4j connection logic
|
||||
// Neo4j connection logic - use the unified graph-db endpoint
|
||||
const dbUrl = localStorage.getItem("NEO4J_URL")
|
||||
const dbUsername = localStorage.getItem("NEO4J_USERNAME")
|
||||
const dbPassword = localStorage.getItem("NEO4J_PASSWORD")
|
||||
|
||||
// Add query parameters if credentials exist
|
||||
// Add query parameters with type=neo4j
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append("type", "neo4j")
|
||||
if (dbUrl) queryParams.append("url", dbUrl)
|
||||
if (dbUsername) queryParams.append("username", dbUsername)
|
||||
if (dbPassword) queryParams.append("password", dbPassword)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
const endpoint = queryString ? `/api/neo4j?${queryString}` : '/api/neo4j'
|
||||
const endpoint = `/api/graph-db?${queryParams.toString()}`
|
||||
|
||||
const response = await fetch(endpoint)
|
||||
|
||||
@ -98,21 +108,21 @@ export function DatabaseConnection({ className }: DatabaseConnectionProps) {
|
||||
setConnectionUrl(dbUrl)
|
||||
}
|
||||
} else {
|
||||
// ArangoDB connection logic
|
||||
// ArangoDB connection logic - use the unified graph-db endpoint with type=arangodb
|
||||
const arangoUrl = localStorage.getItem("arango_url") || "http://localhost:8529"
|
||||
const arangoDb = localStorage.getItem("arango_db") || "txt2kg"
|
||||
const arangoUser = localStorage.getItem("arango_user") || ""
|
||||
const arangoPassword = localStorage.getItem("arango_password") || ""
|
||||
|
||||
// Add query parameters if credentials exist
|
||||
// Add query parameters with type=arangodb
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append("type", "arangodb")
|
||||
if (arangoUrl) queryParams.append("url", arangoUrl)
|
||||
if (arangoDb) queryParams.append("dbName", arangoDb)
|
||||
if (arangoUser) queryParams.append("username", arangoUser)
|
||||
if (arangoPassword) queryParams.append("password", arangoPassword)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
const endpoint = queryString ? `/api/graph-db?${queryString}` : '/api/graph-db'
|
||||
const endpoint = `/api/graph-db?${queryParams.toString()}`
|
||||
|
||||
const response = await fetch(endpoint)
|
||||
|
||||
@ -144,7 +154,8 @@ export function DatabaseConnection({ className }: DatabaseConnectionProps) {
|
||||
// Disconnect from graph database
|
||||
const disconnectGraph = async () => {
|
||||
try {
|
||||
const graphDbType = localStorage.getItem("graph_db_type") || "arangodb"
|
||||
// Use current dbType state which was already determined from server/localStorage
|
||||
const graphDbType = dbType === "Neo4j" ? "neo4j" : "arangodb"
|
||||
const endpoint = graphDbType === "neo4j" ? '/api/neo4j/disconnect' : '/api/graph-db/disconnect'
|
||||
|
||||
const response = await fetch(endpoint, {
|
||||
|
||||
@ -171,9 +171,20 @@ export function SettingsModal() {
|
||||
setIsS3Connected(s3Connected)
|
||||
}
|
||||
|
||||
// Load graph DB type
|
||||
const storedGraphDbType = localStorage.getItem("graph_db_type") || "arangodb"
|
||||
setGraphDbType(storedGraphDbType as GraphDBType)
|
||||
// Load graph DB type - fetch from server if not in localStorage
|
||||
const storedGraphDbType = localStorage.getItem("graph_db_type")
|
||||
if (storedGraphDbType) {
|
||||
setGraphDbType(storedGraphDbType as GraphDBType)
|
||||
} else {
|
||||
// Fetch server's default (from GRAPH_DB_TYPE env var)
|
||||
fetch('/api/settings')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const serverDefault = data.settings?.graph_db_type || 'neo4j'
|
||||
setGraphDbType(serverDefault as GraphDBType)
|
||||
})
|
||||
.catch(() => setGraphDbType('neo4j'))
|
||||
}
|
||||
|
||||
// Load Neo4j settings
|
||||
setNeo4jUrl(localStorage.getItem("neo4j_url") || "")
|
||||
|
||||
@ -37,7 +37,15 @@ export class BackendService {
|
||||
private modelName: string = 'all-MiniLM-L6-v2';
|
||||
private static instance: BackendService;
|
||||
private initialized: boolean = false;
|
||||
private activeGraphDbType: GraphDBType = 'arangodb';
|
||||
private activeGraphDbType: GraphDBType | null = null; // Set at runtime, not build time
|
||||
|
||||
private getRuntimeGraphDbType(): GraphDBType {
|
||||
if (this.activeGraphDbType === null) {
|
||||
this.activeGraphDbType = (process.env.GRAPH_DB_TYPE as GraphDBType) || 'arangodb';
|
||||
console.log(`[BackendService] Initialized activeGraphDbType at runtime: ${this.activeGraphDbType}`);
|
||||
}
|
||||
return this.activeGraphDbType;
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
this.graphDBService = GraphDBService.getInstance();
|
||||
@ -64,16 +72,17 @@ export class BackendService {
|
||||
|
||||
/**
|
||||
* Initialize the backend services
|
||||
* @param graphDbType - Type of graph database to use (neo4j or arangodb)
|
||||
* @param graphDbType - Type of graph database to use (defaults to GRAPH_DB_TYPE env var)
|
||||
*/
|
||||
public async initialize(graphDbType: GraphDBType = 'arangodb'): Promise<void> {
|
||||
this.activeGraphDbType = graphDbType;
|
||||
public async initialize(graphDbType?: GraphDBType): Promise<void> {
|
||||
const dbType = graphDbType || (process.env.GRAPH_DB_TYPE as GraphDBType) || 'arangodb';
|
||||
this.activeGraphDbType = dbType;
|
||||
|
||||
// Initialize Graph Database
|
||||
if (!this.graphDBService.isInitialized()) {
|
||||
try {
|
||||
// Get the appropriate service based on type
|
||||
const graphDbService = getGraphDbService(graphDbType);
|
||||
const graphDbService = getGraphDbService(dbType);
|
||||
|
||||
// Try to get settings from server settings API first
|
||||
let serverSettings: Record<string, string> = {};
|
||||
@ -88,7 +97,7 @@ export class BackendService {
|
||||
console.log('Failed to load settings from server API, falling back to environment variables:', error);
|
||||
}
|
||||
|
||||
if (graphDbType === 'neo4j') {
|
||||
if (dbType === 'neo4j') {
|
||||
// Get Neo4j credentials from server settings first, then fallback to environment
|
||||
const uri = serverSettings.neo4j_url || process.env.NEO4J_URI;
|
||||
const username = serverSettings.neo4j_user || process.env.NEO4J_USER || process.env.NEO4J_USERNAME;
|
||||
@ -107,9 +116,9 @@ export class BackendService {
|
||||
console.log(`Using ArangoDB database: ${dbName}`);
|
||||
await this.graphDBService.initialize('arangodb', url, username, password);
|
||||
}
|
||||
console.log(`${graphDbType} initialized successfully in backend service`);
|
||||
console.log(`${dbType} initialized successfully in backend service`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to initialize ${graphDbType} in backend service:`, error);
|
||||
console.error(`Failed to initialize ${dbType} in backend service:`, error);
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('Development mode: Continuing despite graph database initialization error');
|
||||
} else {
|
||||
@ -151,7 +160,7 @@ export class BackendService {
|
||||
* Get the active graph database type
|
||||
*/
|
||||
public getGraphDbType(): GraphDBType {
|
||||
return this.activeGraphDbType;
|
||||
return this.getRuntimeGraphDbType();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,7 +262,7 @@ export class BackendService {
|
||||
const filteredKeywords = keywords.filter(kw => !this.isStopWord(kw));
|
||||
|
||||
// If using ArangoDB, use its native graph traversal capabilities
|
||||
if (this.activeGraphDbType === 'arangodb') {
|
||||
if (this.getRuntimeGraphDbType() === 'arangodb') {
|
||||
console.log(`Using ArangoDB native graph traversal for keywords: ${filteredKeywords.join(', ')}`);
|
||||
|
||||
try {
|
||||
|
||||
@ -22,18 +22,17 @@
|
||||
/**
|
||||
* Initialize default database settings if not already set
|
||||
* Called before syncing with server to ensure defaults are available
|
||||
* NOTE: Don't set graph_db_type here - let server's GRAPH_DB_TYPE env var control it
|
||||
*/
|
||||
export function initializeDefaultSettings() {
|
||||
if (typeof window === 'undefined') {
|
||||
return; // Only run on client side
|
||||
}
|
||||
|
||||
// Set default graph DB type to ArangoDB if not set
|
||||
if (!localStorage.getItem('graph_db_type')) {
|
||||
localStorage.setItem('graph_db_type', 'arangodb');
|
||||
}
|
||||
|
||||
// Set default ArangoDB settings if not set
|
||||
// Don't set graph_db_type default - let it be controlled by server's GRAPH_DB_TYPE env var
|
||||
// The server will use its environment variable if no client setting is provided
|
||||
|
||||
// Set default connection settings only (not the database type selection)
|
||||
if (!localStorage.getItem('arango_url')) {
|
||||
localStorage.setItem('arango_url', 'http://localhost:8529');
|
||||
}
|
||||
@ -41,6 +40,11 @@ export function initializeDefaultSettings() {
|
||||
if (!localStorage.getItem('arango_db')) {
|
||||
localStorage.setItem('arango_db', 'txt2kg');
|
||||
}
|
||||
|
||||
// Set default Neo4j settings
|
||||
if (!localStorage.getItem('neo4j_url')) {
|
||||
localStorage.setItem('neo4j_url', 'bolt://localhost:7687');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,7 +26,7 @@ export type GraphDBType = 'neo4j' | 'arangodb';
|
||||
export class GraphDBService {
|
||||
private neo4jService: Neo4jService;
|
||||
private arangoDBService: ArangoDBService;
|
||||
private activeDBType: GraphDBType = 'arangodb'; // Default to ArangoDB
|
||||
private activeDBType: GraphDBType | null = null; // Set at runtime, not build time
|
||||
private static instance: GraphDBService;
|
||||
|
||||
private constructor() {
|
||||
@ -34,6 +34,17 @@ export class GraphDBService {
|
||||
this.arangoDBService = ArangoDBService.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active DB type, reading from env at runtime if not set
|
||||
*/
|
||||
private getActiveDBType(): GraphDBType {
|
||||
if (this.activeDBType === null) {
|
||||
this.activeDBType = (process.env.GRAPH_DB_TYPE as GraphDBType) || 'arangodb';
|
||||
console.log(`[GraphDBService] Initialized activeDBType at runtime: ${this.activeDBType}`);
|
||||
}
|
||||
return this.activeDBType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton instance of GraphDBService
|
||||
*/
|
||||
@ -46,24 +57,25 @@ export class GraphDBService {
|
||||
|
||||
/**
|
||||
* Initialize the graph database with the specified type
|
||||
* @param dbType - Type of graph database to use
|
||||
* @param dbType - Type of graph database to use (defaults to GRAPH_DB_TYPE env var)
|
||||
* @param uri - Connection URL
|
||||
* @param username - Database username
|
||||
* @param password - Database password
|
||||
*/
|
||||
public async initialize(dbType: GraphDBType = 'arangodb', uri?: string, username?: string, password?: string): Promise<void> {
|
||||
this.activeDBType = dbType;
|
||||
public async initialize(dbType?: GraphDBType, uri?: string, username?: string, password?: string): Promise<void> {
|
||||
const graphDbType = dbType || (process.env.GRAPH_DB_TYPE as GraphDBType) || 'arangodb';
|
||||
this.activeDBType = graphDbType;
|
||||
|
||||
try {
|
||||
if (dbType === 'neo4j') {
|
||||
if (graphDbType === 'neo4j') {
|
||||
this.neo4jService.initialize(uri, username, password);
|
||||
console.log('Neo4j initialized successfully');
|
||||
} else if (dbType === 'arangodb') {
|
||||
} else if (graphDbType === 'arangodb') {
|
||||
await this.arangoDBService.initialize(uri, undefined, username, password);
|
||||
console.log('ArangoDB initialized successfully');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to initialize ${dbType}:`, error);
|
||||
console.error(`Failed to initialize ${graphDbType}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@ -79,14 +91,14 @@ export class GraphDBService {
|
||||
* Get the active graph database type
|
||||
*/
|
||||
public getDBType(): GraphDBType {
|
||||
return this.activeDBType;
|
||||
return this.getActiveDBType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the active database is initialized
|
||||
*/
|
||||
public isInitialized(): boolean {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
return this.neo4jService.isInitialized();
|
||||
} else {
|
||||
return this.arangoDBService.isInitialized();
|
||||
@ -97,7 +109,7 @@ export class GraphDBService {
|
||||
* Import triples into the active graph database
|
||||
*/
|
||||
public async importTriples(triples: { subject: string; predicate: string; object: string }[]): Promise<void> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
await this.neo4jService.importTriples(triples);
|
||||
} else {
|
||||
await this.arangoDBService.importTriples(triples);
|
||||
@ -121,7 +133,7 @@ export class GraphDBService {
|
||||
[key: string]: any
|
||||
}>;
|
||||
}> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
return await this.neo4jService.getGraphData();
|
||||
} else {
|
||||
return await this.arangoDBService.getGraphData();
|
||||
@ -142,7 +154,7 @@ export class GraphDBService {
|
||||
resultCount: number;
|
||||
}
|
||||
): Promise<void> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
await this.neo4jService.logQuery(query, queryMode, metrics);
|
||||
} else {
|
||||
await this.arangoDBService.logQuery(query, queryMode, metrics);
|
||||
@ -153,7 +165,7 @@ export class GraphDBService {
|
||||
* Get query logs from the active graph database
|
||||
*/
|
||||
public async getQueryLogs(limit: number = 100): Promise<any[]> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
return await this.neo4jService.getQueryLogs(limit);
|
||||
} else {
|
||||
return await this.arangoDBService.getQueryLogs(limit);
|
||||
@ -164,7 +176,7 @@ export class GraphDBService {
|
||||
* Close the connection to the active graph database
|
||||
*/
|
||||
public async close(): Promise<void> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
this.neo4jService.close();
|
||||
} else {
|
||||
this.arangoDBService.close();
|
||||
@ -175,7 +187,7 @@ export class GraphDBService {
|
||||
* Get info about the active graph database driver
|
||||
*/
|
||||
public getDriverInfo(): Record<string, any> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
return this.neo4jService.getDriverInfo();
|
||||
} else {
|
||||
return this.arangoDBService.getDriverInfo();
|
||||
@ -197,7 +209,7 @@ export class GraphDBService {
|
||||
confidence: number;
|
||||
depth?: number;
|
||||
}>> {
|
||||
if (this.activeDBType === 'arangodb') {
|
||||
if (this.getActiveDBType() === 'arangodb') {
|
||||
return await this.arangoDBService.graphTraversal(keywords, maxDepth, maxResults);
|
||||
} else {
|
||||
// Neo4j doesn't have this method yet, return empty array
|
||||
@ -210,7 +222,7 @@ export class GraphDBService {
|
||||
* Clear all data from the active graph database
|
||||
*/
|
||||
public async clearDatabase(): Promise<void> {
|
||||
if (this.activeDBType === 'neo4j') {
|
||||
if (this.getActiveDBType() === 'neo4j') {
|
||||
// TODO: Implement Neo4j clear database functionality
|
||||
throw new Error('Clear database functionality not implemented for Neo4j');
|
||||
} else {
|
||||
|
||||
@ -18,20 +18,34 @@ import { GraphDBService, GraphDBType } from './graph-db-service';
|
||||
import { Neo4jService } from './neo4j';
|
||||
import { ArangoDBService } from './arangodb';
|
||||
|
||||
/**
|
||||
* Get the default graph database type from environment or fallback to arangodb
|
||||
* Note: This is called at runtime, not build time, so process.env should be available
|
||||
*/
|
||||
function getDefaultGraphDbType(): GraphDBType {
|
||||
const envType = process.env.GRAPH_DB_TYPE;
|
||||
console.log(`[graph-db-util] getDefaultGraphDbType: env=${envType}`);
|
||||
return (envType as GraphDBType) || 'arangodb';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate graph database service based on the graph database type.
|
||||
* This is useful for API routes that need direct access to a specific graph database.
|
||||
*
|
||||
* @param graphDbType - The type of graph database to use
|
||||
* @param graphDbType - The type of graph database to use (defaults to GRAPH_DB_TYPE env var)
|
||||
*/
|
||||
export function getGraphDbService(graphDbType: GraphDBType = 'arangodb') {
|
||||
if (graphDbType === 'neo4j') {
|
||||
export function getGraphDbService(graphDbType?: GraphDBType) {
|
||||
const dbType = graphDbType || getDefaultGraphDbType();
|
||||
|
||||
if (dbType === 'neo4j') {
|
||||
return Neo4jService.getInstance();
|
||||
} else if (graphDbType === 'arangodb') {
|
||||
} else if (dbType === 'arangodb') {
|
||||
return ArangoDBService.getInstance();
|
||||
} else {
|
||||
// Default to ArangoDB
|
||||
return ArangoDBService.getInstance();
|
||||
// Default based on environment
|
||||
return getDefaultGraphDbType() === 'neo4j'
|
||||
? Neo4jService.getInstance()
|
||||
: ArangoDBService.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,12 +53,13 @@ export function getGraphDbService(graphDbType: GraphDBType = 'arangodb') {
|
||||
* Initialize the graph database directly (not using GraphDBService).
|
||||
* This is useful for API routes that need direct access to a specific graph database.
|
||||
*
|
||||
* @param graphDbType - The type of graph database to use
|
||||
* @param graphDbType - The type of graph database to use (defaults to GRAPH_DB_TYPE env var)
|
||||
*/
|
||||
export async function initializeGraphDb(graphDbType: GraphDBType = 'arangodb'): Promise<void> {
|
||||
const service = getGraphDbService(graphDbType);
|
||||
export async function initializeGraphDb(graphDbType?: GraphDBType): Promise<void> {
|
||||
const dbType = graphDbType || getDefaultGraphDbType();
|
||||
const service = getGraphDbService(dbType);
|
||||
|
||||
if (graphDbType === 'neo4j') {
|
||||
if (dbType === 'neo4j') {
|
||||
// Get Neo4j credentials from environment
|
||||
const uri = process.env.NEO4J_URI;
|
||||
const username = process.env.NEO4J_USER || process.env.NEO4J_USERNAME;
|
||||
@ -54,7 +69,7 @@ export async function initializeGraphDb(graphDbType: GraphDBType = 'arangodb'):
|
||||
if (service instanceof Neo4jService) {
|
||||
service.initialize(uri, username, password);
|
||||
}
|
||||
} else if (graphDbType === 'arangodb') {
|
||||
} else if (dbType === 'arangodb') {
|
||||
// Get ArangoDB credentials from environment
|
||||
const url = process.env.ARANGODB_URL;
|
||||
const dbName = process.env.ARANGODB_DB;
|
||||
|
||||
@ -60,14 +60,15 @@ export class RemoteBackendService {
|
||||
|
||||
/**
|
||||
* Initialize the remote backend with all required services
|
||||
* @param graphDbType - Type of graph database to use
|
||||
* @param graphDbType - Type of graph database to use (defaults to GRAPH_DB_TYPE env var)
|
||||
*/
|
||||
public async initialize(graphDbType: GraphDBType = 'arangodb'): Promise<void> {
|
||||
console.log('Initializing remote backend...');
|
||||
public async initialize(graphDbType?: GraphDBType): Promise<void> {
|
||||
const dbType = graphDbType || (process.env.GRAPH_DB_TYPE as GraphDBType) || 'arangodb';
|
||||
console.log(`Initializing remote backend with ${dbType}...`);
|
||||
|
||||
// Initialize Graph Database
|
||||
await this.graphDBService.initialize(graphDbType);
|
||||
console.log(`${graphDbType} service initialized`);
|
||||
await this.graphDBService.initialize(dbType);
|
||||
console.log(`${dbType} service initialized`);
|
||||
|
||||
// Initialize Pinecone
|
||||
await this.pineconeService.initialize();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user