-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquery-generator-demo.ts
More file actions
174 lines (149 loc) · 5.44 KB
/
query-generator-demo.ts
File metadata and controls
174 lines (149 loc) · 5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/**
* TQL Query Generator Example
*
* Demonstrates how to use the query generator to analyze JSON structure
* and suggest meaningful EQL-S queries
*/
import { EAVStore, jsonEntityFacts } from '../src/eav-engine.js';
import { QueryGenerator } from '../src/query/query-generator.js';
import { readFileSync } from 'fs';
import { join } from 'path';
// Create an EAV store
const store = new EAVStore();
// Sample JSON data
const loadData = async (source: string): Promise<void> => {
console.log(`📥 Loading data from: ${source}`);
let jsonData: any;
if (source.startsWith('http://') || source.startsWith('https://')) {
// Load from URL
const response = await fetch(source);
if (!response.ok) {
throw new Error(`Failed to fetch data from URL: ${response.statusText}`);
}
jsonData = await response.json();
} else {
// Load from local file
try {
const filePath = join(process.cwd(), source);
const fileContent = readFileSync(filePath, 'utf-8');
jsonData = JSON.parse(fileContent);
} catch (error) {
throw new Error(
`Failed to load file: ${error instanceof Error ? error.message : 'Unknown error'}`
);
}
}
// Ingest data into EAV store
if (Array.isArray(jsonData)) {
// Array of objects - create one entity per array element
for (let i = 0; i < jsonData.length; i++) {
const item = jsonData[i]!;
const entityId = generateEntityId(item, i);
const entityType = inferType(item);
const facts = jsonEntityFacts(entityId, item, entityType);
store.addFacts(facts);
}
} else if (typeof jsonData === 'object') {
// Check if this is a wrapper object with a data array (common API pattern)
const dataArray = extractDataArray(jsonData);
if (dataArray) {
// Process the extracted array
for (let i = 0; i < dataArray.length; i++) {
const item = dataArray[i]!;
const entityId = generateEntityId(item, i);
const entityType = inferType(item);
const facts = jsonEntityFacts(entityId, item, entityType);
store.addFacts(facts);
}
} else {
// Single object or nested structure
const entityType = 'root';
const facts = jsonEntityFacts('root', jsonData, entityType);
store.addFacts(facts);
}
} else {
throw new Error('Data must be a JSON object or array');
}
console.log(`✅ Loaded data successfully`);
console.log(`📊 Store stats:`, store.getStats());
};
const extractDataArray = (jsonData: any): any[] | null => {
// Common patterns for API responses with data arrays
const commonArrayKeys = [
'data',
'results',
'items',
'shows',
'posts',
'users',
'products',
];
for (const key of commonArrayKeys) {
if (jsonData[key] && Array.isArray(jsonData[key])) {
console.log(`📦 Detected data array in '${key}' field`);
return jsonData[key];
}
}
return null;
};
const generateEntityId = (item: any, index: number): string => {
const entityType = inferType(item);
// Try to find a unique identifier using common fields
if (item.id) return `${entityType}:${item.id}`;
if (item._id) return `${entityType}:${item._id}`;
if (item.name) return `${entityType}:${item.name}`;
return `${entityType}:${index}`;
};
const inferType = (item: any): string => {
// Try to infer type from common fields
if (item.type) return item.type;
if (item._type) return item._type;
if (item.kind) return item.kind;
// Infer from structure
if (item.title && item.body) return 'post';
if (item.name && item.email) return 'user';
if (item.subject && item.body) return 'email';
if (item.name && item.price) return 'product';
if (item.albumId && item.url) return 'photo';
if (item.userId && item.title && !item.body) return 'album';
return 'item';
};
// Main function
const main = async () => {
// Get data source from command line arguments
const args = process.argv.slice(2);
if (args.length === 0) {
console.log('Please provide a data source (file path or URL)');
process.exit(1);
}
const dataSource = args[0]!;
try {
// Load data
await loadData(dataSource);
// Generate query suggestions
const generator = new QueryGenerator(store);
const suggestions = generator.generateSuggestions({
maxSuggestions: 10,
includeComplex: true
});
// Display suggestions
console.log('\n📝 Generated Query Suggestions');
console.log('='.repeat(60));
if (suggestions.length === 0) {
console.log('No query suggestions could be generated for this data.');
return;
}
for (const [i, suggestion] of suggestions.entries()) {
console.log(`\n[${i + 1}] ${suggestion.description} (${suggestion.complexity})`);
console.log(` ${suggestion.query}`);
}
} catch (error) {
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
process.exit(1);
}
};
// Run the main function
main().catch(error => {
console.error('Unhandled error:', error);
process.exit(1);
});