hlquery-node-client 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +37 -0
- package/LICENSE +29 -0
- package/README.md +316 -0
- package/example.js +636 -0
- package/examples/basic_usage.js +35 -0
- package/examples/collections.js +40 -0
- package/examples/csv.js +39 -0
- package/examples/documents.js +54 -0
- package/examples/flush.js +128 -0
- package/examples/keys.js +58 -0
- package/examples/pdf.js +40 -0
- package/examples/search.js +101 -0
- package/examples/vector.js +465 -0
- package/index.js +39 -0
- package/lib/Aliases.js +48 -0
- package/lib/Client.js +623 -0
- package/lib/Collections.js +159 -0
- package/lib/Documents.js +244 -0
- package/lib/Exceptions.js +101 -0
- package/lib/Keys.js +85 -0
- package/lib/Overrides.js +53 -0
- package/lib/Request.js +147 -0
- package/lib/Response.js +54 -0
- package/lib/Search.js +350 -0
- package/lib/Stopwords.js +60 -0
- package/lib/Synonyms.js +85 -0
- package/lib/System.js +110 -0
- package/lib/conformance.js +74 -0
- package/package.json +42 -0
- package/test/offline-smoke.js +86 -0
- package/utils/Auth.js +34 -0
- package/utils/CSVParser.js +160 -0
- package/utils/Config.js +57 -0
- package/utils/PDFParser.js +196 -0
- package/utils/Validator.js +143 -0
- package/utils/ranker.js +51 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector Search Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates vector search capabilities with multiple collections:
|
|
5
|
+
* - Creates 4 collections with vector fields
|
|
6
|
+
* - Inserts 10 documents per collection with random embeddings
|
|
7
|
+
* - Performs vector searches to find relationships
|
|
8
|
+
* - Shows similarity-based document retrieval
|
|
9
|
+
*
|
|
10
|
+
* Usage: node examples/vector.js [token]
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const Client = require('../lib/Client');
|
|
14
|
+
|
|
15
|
+
// Configuration
|
|
16
|
+
const baseUrl = 'http://localhost:9200';
|
|
17
|
+
const testToken = process.argv[2] || null;
|
|
18
|
+
|
|
19
|
+
// Helper function to generate random vector
|
|
20
|
+
function generateRandomVector(dimensions = 128) {
|
|
21
|
+
const vector = [];
|
|
22
|
+
for (let i = 0; i < dimensions; i++) {
|
|
23
|
+
vector.push(Math.random() * 2 - 1); // Random value between -1 and 1
|
|
24
|
+
}
|
|
25
|
+
// Normalize the vector
|
|
26
|
+
const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
|
|
27
|
+
return vector.map(val => val / magnitude);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Helper function to generate related vectors (similar to a base vector)
|
|
31
|
+
function generateRelatedVector(baseVector, similarity = 0.8) {
|
|
32
|
+
const related = baseVector.map(val => val * similarity);
|
|
33
|
+
const random = generateRandomVector(baseVector.length);
|
|
34
|
+
const orthogonal = random.map((val, i) => val * (1 - similarity));
|
|
35
|
+
return related.map((val, i) => val + orthogonal[i]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Helper function to print results
|
|
39
|
+
function printResult(title, response, printBody = true) {
|
|
40
|
+
console.log('='.repeat(80));
|
|
41
|
+
console.log(`TEST: ${title}`);
|
|
42
|
+
console.log('-'.repeat(80));
|
|
43
|
+
|
|
44
|
+
if (response) {
|
|
45
|
+
const status = response.getStatusCode();
|
|
46
|
+
const body = response.getBody();
|
|
47
|
+
|
|
48
|
+
console.log(`Status Code: ${status}`);
|
|
49
|
+
|
|
50
|
+
if (printBody && body) {
|
|
51
|
+
console.log('Response Body:');
|
|
52
|
+
if (typeof body === 'object') {
|
|
53
|
+
console.log(JSON.stringify(body, null, 2));
|
|
54
|
+
} else {
|
|
55
|
+
console.log(body);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (status >= 200 && status < 300) {
|
|
60
|
+
console.log('✓ SUCCESS');
|
|
61
|
+
} else {
|
|
62
|
+
console.log('✗ FAILED');
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
console.log('Invalid response');
|
|
66
|
+
}
|
|
67
|
+
console.log('\n');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Helper function to print vector query
|
|
71
|
+
function printVectorQuery(collectionName, vectorQuery, params = {}) {
|
|
72
|
+
console.log('\n' + '='.repeat(80));
|
|
73
|
+
console.log('VECTOR QUERY');
|
|
74
|
+
console.log('='.repeat(80));
|
|
75
|
+
console.log(`Collection: ${collectionName}`);
|
|
76
|
+
console.log(`Vector Dimensions: ${vectorQuery.length}`);
|
|
77
|
+
console.log(`Vector (first 10 values): [${vectorQuery.slice(0, 10).map(v => v.toFixed(4)).join(', ')}...]`);
|
|
78
|
+
console.log(`Limit: ${params.limit || 10}`);
|
|
79
|
+
console.log(`Threshold: ${params.threshold || 0.0}`);
|
|
80
|
+
console.log(`Normalize: ${params.normalize !== undefined ? params.normalize : true}`);
|
|
81
|
+
if (params.field_name) {
|
|
82
|
+
console.log(`Field Name: ${params.field_name}`);
|
|
83
|
+
}
|
|
84
|
+
console.log('='.repeat(80) + '\n');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Main function
|
|
88
|
+
async function main() {
|
|
89
|
+
console.log('=== hlquery Vector Search Example ===\n');
|
|
90
|
+
|
|
91
|
+
// Create client
|
|
92
|
+
const client = new Client(baseUrl);
|
|
93
|
+
if (testToken) {
|
|
94
|
+
client.setAuthToken(testToken, 'bearer');
|
|
95
|
+
console.log(`Using authentication token: ${testToken.substring(0, 8)}...\n`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Collection names
|
|
99
|
+
const collections = [
|
|
100
|
+
'products',
|
|
101
|
+
'articles',
|
|
102
|
+
'images',
|
|
103
|
+
'documents'
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
// Collection schemas with vector fields
|
|
107
|
+
const schemas = {
|
|
108
|
+
products: {
|
|
109
|
+
fields: [
|
|
110
|
+
{ name: 'name', type: 'string' },
|
|
111
|
+
{ name: 'description', type: 'string' },
|
|
112
|
+
{ name: 'embedding', type: 'float[]' }
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
articles: {
|
|
116
|
+
fields: [
|
|
117
|
+
{ name: 'title', type: 'string' },
|
|
118
|
+
{ name: 'content', type: 'string' },
|
|
119
|
+
{ name: 'embedding', type: 'float[]' }
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
images: {
|
|
123
|
+
fields: [
|
|
124
|
+
{ name: 'filename', type: 'string' },
|
|
125
|
+
{ name: 'caption', type: 'string' },
|
|
126
|
+
{ name: 'embedding', type: 'float[]' }
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
documents: {
|
|
130
|
+
fields: [
|
|
131
|
+
{ name: 'title', type: 'string' },
|
|
132
|
+
{ name: 'text', type: 'string' },
|
|
133
|
+
{ name: 'embedding', type: 'float[]' }
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Generate base vectors for each collection (for creating related documents)
|
|
139
|
+
const baseVectors = {};
|
|
140
|
+
collections.forEach(col => {
|
|
141
|
+
baseVectors[col] = generateRandomVector(128);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// ----------------------------------------------------------------====================================
|
|
145
|
+
// CREATE COLLECTIONS
|
|
146
|
+
// ----------------------------------------------------------------====================================
|
|
147
|
+
console.log('\n' + '#'.repeat(80));
|
|
148
|
+
console.log('# CREATING COLLECTIONS');
|
|
149
|
+
console.log('#'.repeat(80) + '\n');
|
|
150
|
+
|
|
151
|
+
for (const collectionName of collections) {
|
|
152
|
+
try {
|
|
153
|
+
// Check if collection exists, delete if it does
|
|
154
|
+
const existing = await client.getCollection(collectionName);
|
|
155
|
+
if (existing.getStatusCode() === 200) {
|
|
156
|
+
console.log(`Collection ${collectionName} exists, deleting...`);
|
|
157
|
+
await client.collections().delete(collectionName);
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
// Collection doesn't exist, that's fine
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Create collection
|
|
164
|
+
const createResult = await client.collections().create(collectionName, schemas[collectionName]);
|
|
165
|
+
if (createResult.isSuccess()) {
|
|
166
|
+
console.log(`✓ Created collection: ${collectionName}`);
|
|
167
|
+
} else {
|
|
168
|
+
console.log(`✗ Failed to create collection: ${collectionName}`);
|
|
169
|
+
console.log(` Error: ${createResult.getError()}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
console.log('');
|
|
173
|
+
|
|
174
|
+
// ----------------------------------------------------------------====================================
|
|
175
|
+
// INSERT DOCUMENTS
|
|
176
|
+
// ----------------------------------------------------------------====================================
|
|
177
|
+
console.log('\n' + '#'.repeat(80));
|
|
178
|
+
console.log('# INSERTING DOCUMENTS');
|
|
179
|
+
console.log('#'.repeat(80) + '\n');
|
|
180
|
+
|
|
181
|
+
const allDocuments = {};
|
|
182
|
+
|
|
183
|
+
for (const collectionName of collections) {
|
|
184
|
+
console.log(`Inserting documents into ${collectionName}...`);
|
|
185
|
+
const documents = [];
|
|
186
|
+
const baseVector = baseVectors[collectionName];
|
|
187
|
+
|
|
188
|
+
for (let i = 1; i <= 10; i++) {
|
|
189
|
+
// Create documents with varying similarity to base vector
|
|
190
|
+
const similarity = 0.5 + (i / 10) * 0.4; // Range from 0.5 to 0.9
|
|
191
|
+
const embedding = generateRelatedVector(baseVector, similarity);
|
|
192
|
+
|
|
193
|
+
let doc;
|
|
194
|
+
switch (collectionName) {
|
|
195
|
+
case 'products':
|
|
196
|
+
doc = {
|
|
197
|
+
id: `product_${i}`,
|
|
198
|
+
name: `Product ${i}`,
|
|
199
|
+
description: `This is product number ${i} with similarity ${similarity.toFixed(2)}`,
|
|
200
|
+
embedding: embedding
|
|
201
|
+
};
|
|
202
|
+
break;
|
|
203
|
+
case 'articles':
|
|
204
|
+
doc = {
|
|
205
|
+
id: `article_${i}`,
|
|
206
|
+
title: `Article ${i}`,
|
|
207
|
+
content: `This is article number ${i} with similarity ${similarity.toFixed(2)}`,
|
|
208
|
+
embedding: embedding
|
|
209
|
+
};
|
|
210
|
+
break;
|
|
211
|
+
case 'images':
|
|
212
|
+
doc = {
|
|
213
|
+
id: `image_${i}`,
|
|
214
|
+
filename: `image_${i}.jpg`,
|
|
215
|
+
caption: `Image ${i} with similarity ${similarity.toFixed(2)}`,
|
|
216
|
+
embedding: embedding
|
|
217
|
+
};
|
|
218
|
+
break;
|
|
219
|
+
case 'documents':
|
|
220
|
+
doc = {
|
|
221
|
+
id: `doc_${i}`,
|
|
222
|
+
title: `Document ${i}`,
|
|
223
|
+
text: `This is document number ${i} with similarity ${similarity.toFixed(2)}`,
|
|
224
|
+
embedding: embedding
|
|
225
|
+
};
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
documents.push(doc);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Bulk import
|
|
233
|
+
const importResult = await client.documents().import(collectionName, documents);
|
|
234
|
+
if (importResult.isSuccess()) {
|
|
235
|
+
console.log(`✓ Inserted ${documents.length} documents into ${collectionName}`);
|
|
236
|
+
allDocuments[collectionName] = documents;
|
|
237
|
+
} else {
|
|
238
|
+
console.log(`✗ Failed to insert documents into ${collectionName}`);
|
|
239
|
+
console.log(` Error: ${importResult.getError()}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
console.log('');
|
|
243
|
+
|
|
244
|
+
// Wait a bit for indexing
|
|
245
|
+
console.log('Waiting for documents to be indexed...');
|
|
246
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
247
|
+
console.log('');
|
|
248
|
+
|
|
249
|
+
// ----------------------------------------------------------------====================================
|
|
250
|
+
// VECTOR SEARCH - Find Similar Documents
|
|
251
|
+
// ----------------------------------------------------------------====================================
|
|
252
|
+
console.log('\n' + '#'.repeat(80));
|
|
253
|
+
console.log('# VECTOR SEARCH - Finding Relationships');
|
|
254
|
+
console.log('#'.repeat(80) + '\n');
|
|
255
|
+
|
|
256
|
+
// Test 1: Search in products collection using base vector
|
|
257
|
+
console.log('TEST 1: Search in products collection using base vector\n');
|
|
258
|
+
const productsQuery = baseVectors.products;
|
|
259
|
+
printVectorQuery('products', productsQuery, { limit: 5, threshold: 0.0, normalize: true });
|
|
260
|
+
|
|
261
|
+
const productsSearch = await client.vectorSearch('products', {
|
|
262
|
+
vector_query: productsQuery,
|
|
263
|
+
limit: 5,
|
|
264
|
+
threshold: 0.0,
|
|
265
|
+
normalize: true
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (productsSearch.isSuccess()) {
|
|
269
|
+
const body = productsSearch.getBody();
|
|
270
|
+
console.log('RESULTS:');
|
|
271
|
+
if (body.hits && body.hits.length > 0) {
|
|
272
|
+
body.hits.forEach((hit, index) => {
|
|
273
|
+
console.log(`\n ${index + 1}. Document ID: ${hit.document?.id || hit.id}`);
|
|
274
|
+
console.log(` Name: ${hit.document?.name || 'N/A'}`);
|
|
275
|
+
console.log(` Similarity Score: ${hit.similarity_score !== undefined ? hit.similarity_score.toFixed(4) : 'N/A'}`);
|
|
276
|
+
if (hit.document?.embedding) {
|
|
277
|
+
const emb = hit.document.embedding;
|
|
278
|
+
if (Array.isArray(emb) && emb.length > 0) {
|
|
279
|
+
console.log(` Embedding (first 5): [${emb.slice(0, 5).map(v => v.toFixed(4)).join(', ')}...]`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
} else {
|
|
284
|
+
console.log(' No results found');
|
|
285
|
+
}
|
|
286
|
+
console.log(`\nTotal found: ${body.found || 0}`);
|
|
287
|
+
} else {
|
|
288
|
+
console.log(`✗ Search failed: ${productsSearch.getError()}`);
|
|
289
|
+
}
|
|
290
|
+
console.log('');
|
|
291
|
+
|
|
292
|
+
// Test 2: Search in articles collection using a related vector
|
|
293
|
+
console.log('TEST 2: Search in articles collection using related vector\n');
|
|
294
|
+
const articlesQuery = generateRelatedVector(baseVectors.articles, 0.85);
|
|
295
|
+
printVectorQuery('articles', articlesQuery, { limit: 5, threshold: 0.5, normalize: true });
|
|
296
|
+
|
|
297
|
+
const articlesSearch = await client.vectorSearch('articles', {
|
|
298
|
+
vector_query: articlesQuery,
|
|
299
|
+
limit: 5,
|
|
300
|
+
threshold: 0.5,
|
|
301
|
+
normalize: true
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
if (articlesSearch.isSuccess()) {
|
|
305
|
+
const body = articlesSearch.getBody();
|
|
306
|
+
console.log('RESULTS:');
|
|
307
|
+
if (body.hits && body.hits.length > 0) {
|
|
308
|
+
body.hits.forEach((hit, index) => {
|
|
309
|
+
console.log(`\n ${index + 1}. Document ID: ${hit.document?.id || hit.id}`);
|
|
310
|
+
console.log(` Title: ${hit.document?.title || 'N/A'}`);
|
|
311
|
+
console.log(` Similarity Score: ${hit.similarity_score !== undefined ? hit.similarity_score.toFixed(4) : 'N/A'}`);
|
|
312
|
+
});
|
|
313
|
+
} else {
|
|
314
|
+
console.log(' No results found (threshold too high)');
|
|
315
|
+
}
|
|
316
|
+
console.log(`\nTotal found: ${body.found || 0}`);
|
|
317
|
+
} else {
|
|
318
|
+
console.log(`✗ Search failed: ${articlesSearch.getError()}`);
|
|
319
|
+
}
|
|
320
|
+
console.log('');
|
|
321
|
+
|
|
322
|
+
// Test 3: Cross-collection search - find similar documents across collections
|
|
323
|
+
console.log('TEST 3: Cross-collection search - Find similar documents in images collection\n');
|
|
324
|
+
const imagesQuery = baseVectors.images;
|
|
325
|
+
printVectorQuery('images', imagesQuery, { limit: 10, threshold: 0.0, normalize: true });
|
|
326
|
+
|
|
327
|
+
const imagesSearch = await client.vectorSearch('images', {
|
|
328
|
+
vector_query: imagesQuery,
|
|
329
|
+
limit: 10,
|
|
330
|
+
threshold: 0.0,
|
|
331
|
+
normalize: true
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
if (imagesSearch.isSuccess()) {
|
|
335
|
+
const body = imagesSearch.getBody();
|
|
336
|
+
console.log('RESULTS:');
|
|
337
|
+
if (body.hits && body.hits.length > 0) {
|
|
338
|
+
body.hits.forEach((hit, index) => {
|
|
339
|
+
console.log(`\n ${index + 1}. Document ID: ${hit.document?.id || hit.id}`);
|
|
340
|
+
console.log(` Filename: ${hit.document?.filename || 'N/A'}`);
|
|
341
|
+
console.log(` Caption: ${hit.document?.caption || 'N/A'}`);
|
|
342
|
+
console.log(` Similarity Score: ${hit.similarity_score !== undefined ? hit.similarity_score.toFixed(4) : 'N/A'}`);
|
|
343
|
+
});
|
|
344
|
+
} else {
|
|
345
|
+
console.log(' No results found');
|
|
346
|
+
}
|
|
347
|
+
console.log(`\nTotal found: ${body.found || 0}`);
|
|
348
|
+
} else {
|
|
349
|
+
console.log(`✗ Search failed: ${imagesSearch.getError()}`);
|
|
350
|
+
}
|
|
351
|
+
console.log('');
|
|
352
|
+
|
|
353
|
+
// Test 4: Search with high threshold to find only very similar documents
|
|
354
|
+
console.log('TEST 4: High threshold search - Find only very similar documents\n');
|
|
355
|
+
const documentsQuery = baseVectors.documents;
|
|
356
|
+
printVectorQuery('documents', documentsQuery, { limit: 5, threshold: 0.7, normalize: true });
|
|
357
|
+
|
|
358
|
+
const documentsSearch = await client.vectorSearch('documents', {
|
|
359
|
+
vector_query: documentsQuery,
|
|
360
|
+
limit: 5,
|
|
361
|
+
threshold: 0.7,
|
|
362
|
+
normalize: true
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
if (documentsSearch.isSuccess()) {
|
|
366
|
+
const body = documentsSearch.getBody();
|
|
367
|
+
console.log('RESULTS:');
|
|
368
|
+
if (body.hits && body.hits.length > 0) {
|
|
369
|
+
body.hits.forEach((hit, index) => {
|
|
370
|
+
console.log(`\n ${index + 1}. Document ID: ${hit.document?.id || hit.id}`);
|
|
371
|
+
console.log(` Title: ${hit.document?.title || 'N/A'}`);
|
|
372
|
+
console.log(` Similarity Score: ${hit.similarity_score !== undefined ? hit.similarity_score.toFixed(4) : 'N/A'}`);
|
|
373
|
+
});
|
|
374
|
+
} else {
|
|
375
|
+
console.log(' No results found (threshold too high - no documents with similarity > 0.7)');
|
|
376
|
+
}
|
|
377
|
+
console.log(`\nTotal found: ${body.found || 0}`);
|
|
378
|
+
} else {
|
|
379
|
+
console.log(`✗ Search failed: ${documentsSearch.getError()}`);
|
|
380
|
+
}
|
|
381
|
+
console.log('');
|
|
382
|
+
|
|
383
|
+
// Test 5: Find relationships between collections
|
|
384
|
+
console.log('TEST 5: Find relationships - Search products using articles base vector\n');
|
|
385
|
+
const crossQuery = baseVectors.articles;
|
|
386
|
+
printVectorQuery('products', crossQuery, {
|
|
387
|
+
limit: 3,
|
|
388
|
+
threshold: 0.0,
|
|
389
|
+
normalize: true,
|
|
390
|
+
note: 'Using articles base vector to search products (cross-collection similarity)'
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const crossSearch = await client.vectorSearch('products', {
|
|
394
|
+
vector_query: crossQuery,
|
|
395
|
+
limit: 3,
|
|
396
|
+
threshold: 0.0,
|
|
397
|
+
normalize: true
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
if (crossSearch.isSuccess()) {
|
|
401
|
+
const body = crossSearch.getBody();
|
|
402
|
+
console.log('RESULTS (Cross-collection similarity):');
|
|
403
|
+
if (body.hits && body.hits.length > 0) {
|
|
404
|
+
body.hits.forEach((hit, index) => {
|
|
405
|
+
console.log(`\n ${index + 1}. Document ID: ${hit.document?.id || hit.id}`);
|
|
406
|
+
console.log(` Name: ${hit.document?.name || 'N/A'}`);
|
|
407
|
+
console.log(` Similarity Score: ${hit.similarity_score !== undefined ? hit.similarity_score.toFixed(4) : 'N/A'}`);
|
|
408
|
+
console.log(` Note: Lower scores indicate less similarity across collections`);
|
|
409
|
+
});
|
|
410
|
+
} else {
|
|
411
|
+
console.log(' No results found');
|
|
412
|
+
}
|
|
413
|
+
console.log(`\nTotal found: ${body.found || 0}`);
|
|
414
|
+
} else {
|
|
415
|
+
console.log(`✗ Search failed: ${crossSearch.getError()}`);
|
|
416
|
+
}
|
|
417
|
+
console.log('');
|
|
418
|
+
|
|
419
|
+
// ----------------------------------------------------------------====================================
|
|
420
|
+
// SUMMARY
|
|
421
|
+
// ----------------------------------------------------------------====================================
|
|
422
|
+
console.log('\n' + '#'.repeat(80));
|
|
423
|
+
console.log('# SUMMARY');
|
|
424
|
+
console.log('#'.repeat(80) + '\n');
|
|
425
|
+
|
|
426
|
+
console.log('Created Collections:');
|
|
427
|
+
collections.forEach(col => {
|
|
428
|
+
console.log(` - ${col}`);
|
|
429
|
+
});
|
|
430
|
+
console.log('');
|
|
431
|
+
|
|
432
|
+
console.log('Documents Inserted:');
|
|
433
|
+
collections.forEach(col => {
|
|
434
|
+
const count = allDocuments[col] ? allDocuments[col].length : 0;
|
|
435
|
+
console.log(` - ${col}: ${count} documents`);
|
|
436
|
+
});
|
|
437
|
+
console.log('');
|
|
438
|
+
|
|
439
|
+
console.log('Vector Search Tests Performed:');
|
|
440
|
+
console.log(' 1. Products collection search (base vector, threshold 0.0)');
|
|
441
|
+
console.log(' 2. Articles collection search (related vector, threshold 0.5)');
|
|
442
|
+
console.log(' 3. Images collection search (base vector, all results)');
|
|
443
|
+
console.log(' 4. Documents collection search (base vector, high threshold 0.7)');
|
|
444
|
+
console.log(' 5. Cross-collection search (articles vector → products collection)');
|
|
445
|
+
console.log('');
|
|
446
|
+
|
|
447
|
+
console.log('Key Observations:');
|
|
448
|
+
console.log(' - Documents with higher similarity scores are more related');
|
|
449
|
+
console.log(' - Threshold parameter filters results by minimum similarity');
|
|
450
|
+
console.log(' - Vector normalization ensures consistent similarity calculations');
|
|
451
|
+
console.log(' - Cross-collection searches can find relationships across different data types');
|
|
452
|
+
console.log('');
|
|
453
|
+
|
|
454
|
+
console.log('Usage: node examples/vector.js [token]');
|
|
455
|
+
console.log('');
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Run main function
|
|
459
|
+
main().catch(error => {
|
|
460
|
+
console.error('Fatal error:', error);
|
|
461
|
+
if (error.stack) {
|
|
462
|
+
console.error(error.stack);
|
|
463
|
+
}
|
|
464
|
+
process.exit(1);
|
|
465
|
+
});
|
package/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hlquery Node.js Client - Main Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2021-2026, Carlos F. Ferry <carlos.ferry@gmail.com>
|
|
5
|
+
*
|
|
6
|
+
* This file is part of hlquery, released under the BSD License version 3.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const Client = require('./lib/Client');
|
|
10
|
+
|
|
11
|
+
// Export main client class
|
|
12
|
+
module.exports = Client;
|
|
13
|
+
|
|
14
|
+
// Export all classes for advanced usage
|
|
15
|
+
module.exports.Client = Client;
|
|
16
|
+
module.exports.Request = require('./lib/Request');
|
|
17
|
+
module.exports.Response = require('./lib/Response');
|
|
18
|
+
module.exports.Collections = require('./lib/Collections');
|
|
19
|
+
module.exports.Documents = require('./lib/Documents');
|
|
20
|
+
module.exports.Search = require('./lib/Search');
|
|
21
|
+
module.exports.Keys = require('./lib/Keys');
|
|
22
|
+
module.exports.Aliases = require('./lib/Aliases');
|
|
23
|
+
module.exports.Overrides = require('./lib/Overrides');
|
|
24
|
+
module.exports.Synonyms = require('./lib/Synonyms');
|
|
25
|
+
module.exports.Stopwords = require('./lib/Stopwords');
|
|
26
|
+
module.exports.System = require('./lib/System');
|
|
27
|
+
|
|
28
|
+
// Export exceptions
|
|
29
|
+
module.exports.Exceptions = require('./lib/Exceptions');
|
|
30
|
+
|
|
31
|
+
// Export utilities
|
|
32
|
+
module.exports.Utils = {
|
|
33
|
+
Config: require('./utils/Config'),
|
|
34
|
+
Validator: require('./utils/Validator'),
|
|
35
|
+
Auth: require('./utils/Auth'),
|
|
36
|
+
Ranker: require('./utils/ranker'),
|
|
37
|
+
PDFParser: require('./utils/PDFParser'),
|
|
38
|
+
CSVParser: require('./utils/CSVParser')
|
|
39
|
+
};
|
package/lib/Aliases.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hlquery Node.js Client - Aliases API
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2021-2026, Carlos F. Ferry <carlos.ferry@gmail.com>
|
|
5
|
+
*
|
|
6
|
+
* This file is part of hlquery, released under the BSD License version 3.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const Validator = require('../utils/Validator');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Aliases API operations
|
|
13
|
+
*/
|
|
14
|
+
class Aliases {
|
|
15
|
+
constructor(request) {
|
|
16
|
+
this.request = request;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async list() {
|
|
20
|
+
return await this.request.execute('GET', '/aliases');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async get(name) {
|
|
24
|
+
Validator.validateCollectionName(name);
|
|
25
|
+
return await this.request.execute('GET', `/aliases/${encodeURIComponent(name)}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async create(name, params) {
|
|
29
|
+
Validator.validateCollectionName(name);
|
|
30
|
+
return await this.request.execute('POST', `/aliases/${encodeURIComponent(name)}`, params);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async update(name, params) {
|
|
34
|
+
Validator.validateCollectionName(name);
|
|
35
|
+
return await this.request.execute('PUT', `/aliases/${encodeURIComponent(name)}`, params);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async upsert(name, params) {
|
|
39
|
+
return await this.create(name, params);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async delete(name) {
|
|
43
|
+
Validator.validateCollectionName(name);
|
|
44
|
+
return await this.request.execute('DELETE', `/aliases/${encodeURIComponent(name)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = Aliases;
|