Node.js Client Examples
Comprehensive examples for the hlquery Node.js client library.
Example Files
The Node.js client includes several example files demonstrating different aspects of the API:
- basic_usage.js - Basic client initialization and simple operations
- collections.js - Collection management operations
- documents.js - Document CRUD operations
- search.js - Various search patterns and options
- vector.js - Vector search capabilities with multiple collections
Running Examples
Main Example File
The main example file (example.js) provides a comprehensive demonstration of all API features:
# Run all examples (default)
node example.js
# Run specific command
node example.js cols # List collections
node example.js docs my_collection # List documents in collection
node example.js status # Show server health and status
node example.js help # Show help message
Individual Example Files
# Basic usage
node examples/basic_usage.js
# Collections
node examples/collections.js
# Documents
node examples/documents.js
# Search
node examples/search.js
# Vector search
node examples/vector.js
Example Output
Running node examples/basic_usage.js against a local server can look like this:
Health Status: 200
Health Body: {
auth_enabled: false,
auth_required: false,
demo_mode: false,
engine: 'epoll',
health_degraded: false,
loaded_modules: [ 'test', 'banned', 'lang', 'analytics' ],
readonly_mode: false,
server: 'hlquery',
socket_engine: 'epoll',
status: 'ok',
version: '1.0'
}
Found 0 collections
That means the Node.js client returns a Response object, and getBody() gives you the parsed JSON body you can inspect directly.
Table of Contents
- Basic Operations
- Collection Management
- Document Operations
- Search Examples
- Advanced Features
- Error Handling
- Real-World Scenarios
Basic Operations
Initialize Client
const Client = require('./lib/Client');
// Basic initialization
const client = new Client('http://localhost:9200');
// With authentication
const client = new Client('http://localhost:9200', {
token: 'your_token_here',
auth_method: 'bearer'
});
// With timeout
const client = new Client('http://localhost:9200', {
timeout: 5000 // 5 seconds
});
Health Check
async function checkHealth() {
const health = await client.health();
if (health.isSuccess()) {
const body = health.getBody();
console.log('Server status:', body.status);
console.log('Engine:', body.engine);
console.log('Version:', body.version);
} else {
console.error('Health check failed:', health.getError());
}
}
Typical health.getBody() result:
{
auth_enabled: false,
auth_required: false,
demo_mode: false,
engine: 'epoll',
health_degraded: false,
loaded_modules: ['test', 'banned', 'lang', 'analytics'],
readonly_mode: false,
server: 'hlquery',
socket_engine: 'epoll',
status: 'ok',
version: '1.0'
}
Server Statistics
async function getStats() {
const stats = await client.stats();
const body = stats.getBody();
console.log('Collections:', body.collections?.total);
console.log('Documents:', body.documents?.total);
console.log('Memory:', body.memory);
console.log('Uptime:', body.uptime);
}
Typical response shape:
{
collections: {
total: 12
},
documents: {
total: 100100
},
memory: {
used: 12345678
},
uptime: 3456
}
The exact numbers depend on your running server state. The important part is the body shape returned by stats.getBody().
Collection Management
Create Collection
async function createProductCollection() {
const schema = {
fields: [
{ name: 'title', type: 'string' },
{ name: 'description', type: 'string' },
{ name: 'price', type: 'float' },
{ name: 'category', type: 'string' },
{ name: 'tags', type: 'string[]' },
{ name: 'in_stock', type: 'bool' },
{ name: 'rating', type: 'float' }
]
};
const result = await client.collections().create('products', schema);
if (result.isSuccess()) {
console.log('Collection created successfully');
} else {
console.error('Failed to create collection:', result.getError());
}
}
List Collections
async function listCollections() {
const result = await client.listCollections(0, 10);
if (result.isSuccess()) {
const body = result.getBody();
const collections = body.collections || [];
console.log(`Found ${collections.length} collections:`);
collections.forEach(col => {
console.log(`- ${col.name} (${col.num_documents} documents)`);
});
}
}
Get Collection Details
async function getCollectionInfo(collectionName) {
const result = await client.getCollection(collectionName);
if (result.isSuccess()) {
const body = result.getBody();
console.log('Collection:', body.name);
console.log('Fields:', body.fields);
console.log('Document count:', body.num_documents);
}
}
Update Collection Schema
async function addFieldToCollection(collectionName) {
const result = await client.getCollection(collectionName);
if (result.isSuccess()) {
const body = result.getBody();
const updatedSchema = {
fields: [
...body.fields,
{ name: 'new_field', type: 'string' }
]
};
const updateResult = await client.collections().update(collectionName, {
fields: updatedSchema.fields
});
if (updateResult.isSuccess()) {
console.log('Collection updated successfully');
}
}
}
Delete Collection
async function deleteCollection(collectionName) {
const result = await client.deleteCollection(collectionName);
if (result.isSuccess()) {
console.log('Collection deleted successfully');
} else {
console.error('Failed to delete collection:', result.getError());
}
}
Document Operations
Add Single Document
async function addProduct() {
const product = {
id: 'prod_001',
title: 'Wireless Headphones',
description: 'High-quality wireless headphones with noise cancellation',
price: 199.99,
category: 'electronics',
tags: ['audio', 'wireless', 'premium'],
in_stock: true,
rating: 4.5
};
const result = await client.documents().add('products', product);
if (result.isSuccess()) {
console.log('Product added:', result.getBody());
}
}
Update Document
async function updateProduct(productId) {
const updates = {
price: 179.99, // Price drop
in_stock: false
};
const result = await client.documents().update('products', productId, updates);
if (result.isSuccess()) {
console.log('Product updated successfully');
}
}
Get Document
async function getProduct(productId) {
const result = await client.getDocument('products', productId);
if (result.isSuccess()) {
const product = result.getBody();
console.log('Product:', product.title);
console.log('Price:', product.price);
console.log('In stock:', product.in_stock);
}
}
List Documents with Pagination
async function listProducts(page = 0, pageSize = 10) {
const offset = page * pageSize;
const result = await client.listDocuments('products', offset, pageSize);
if (result.isSuccess()) {
const body = result.getBody();
const documents = body.documents || [];
console.log(`Page ${page + 1} (${documents.length} products):`);
documents.forEach(doc => {
console.log(`- ${doc.title}: $${doc.price}`);
});
}
}
Bulk Import Documents
async function importProducts() {
const products = [
{
id: 'prod_001',
title: 'Laptop',
price: 999.99,
category: 'computers',
in_stock: true
},
{
id: 'prod_002',
title: 'Mouse',
price: 29.99,
category: 'accessories',
in_stock: true
},
{
id: 'prod_003',
title: 'Keyboard',
price: 79.99,
category: 'accessories',
in_stock: false
}
];
const result = await client.documents().import('products', products);
if (result.isSuccess()) {
const body = result.getBody();
console.log(`Imported ${body.num_imported} products`);
}
}
Delete Document
async function deleteProduct(productId) {
const result = await client.deleteDocument('products', productId);
if (result.isSuccess()) {
console.log('Product deleted successfully');
}
}
Search Examples
Basic Search
async function searchProducts(query) {
const result = await client.search('products', {
q: query,
query_by: 'title,description',
limit: 10
});
if (result.isSuccess()) {
const body = result.getBody();
const hits = body.hits || [];
console.log(`Found ${hits.length} results:`);
hits.forEach(hit => {
console.log(`- ${hit.document.title} (score: ${hit.text_match})`);
});
}
}
Search with Filters
async function searchWithFilters() {
const result = await client.search('products', {
q: 'laptop',
query_by: 'title',
filter_by: 'price:>500 && in_stock:true',
sort_by: 'price:asc',
limit: 20
});
if (result.isSuccess()) {
const body = result.getBody();
console.log(`Found ${body.found} products`);
}
}
Search with Facets
async function searchWithFacets() {
const result = await client.search('products', {
q: '*',
query_by: 'title',
facet_by: 'category,rating',
limit: 10
});
if (result.isSuccess()) {
const body = result.getBody();
const facets = body.facet_counts || [];
facets.forEach(facet => {
console.log(`\n${facet.field_name}:`);
facet.counts.forEach(count => {
console.log(` ${count.value}: ${count.count}`);
});
});
}
}
Multi-Collection Search
async function multiCollectionSearch() {
const searches = [
{ collection: 'products', q: 'laptop', query_by: 'title' },
{ collection: 'articles', q: 'laptop', query_by: 'content' },
{ collection: 'reviews', q: 'laptop', query_by: 'text' }
];
const result = await client.multiSearch(searches);
if (result.isSuccess()) {
const body = result.getBody();
const results = body.results || [];
results.forEach((searchResult, index) => {
console.log(`\nCollection: ${searches[index].collection}`);
console.log(`Found: ${searchResult.found} results`);
});
}
}
Vector Search
async function vectorSearch() {
// Assuming you have embeddings for your query
const queryVector = [0.1, 0.2, 0.3, 0.4, 0.5]; // Your embedding vector
const result = await client.vectorSearch('products', {
vector: queryVector,
limit: 10,
threshold: 0.7
});
if (result.isSuccess()) {
const body = result.getBody();
const hits = body.hits || [];
hits.forEach(hit => {
console.log(`- ${hit.document.title} (similarity: ${hit.vector_distance})`);
});
}
}
Advanced Features
Search with Highlighting
async function searchWithHighlighting(query) {
const result = await client.search('products', {
q: query,
query_by: 'title,description',
highlight_fields: 'title,description',
highlight_affix_num_tokens: 4,
limit: 10
});
if (result.isSuccess()) {
const body = result.getBody();
const hits = body.hits || [];
hits.forEach(hit => {
console.log(`Title: ${hit.highlights?.title || hit.document.title}`);
console.log(`Description: ${hit.highlights?.description || hit.document.description}`);
});
}
}
Search with Typo Tolerance
async function searchWithTypos(query) {
const result = await client.search('products', {
q: query,
query_by: 'title',
typo_tolerance: 'auto', // or 'off', 'min', 'max'
limit: 10
});
if (result.isSuccess()) {
const body = result.getBody();
console.log(`Found ${body.found} results (with typo tolerance)`);
}
}
Search with Synonyms
async function searchWithSynonyms(query) {
const result = await client.search('products', {
q: query,
query_by: 'title',
use_synonyms: true,
limit: 10
});
if (result.isSuccess()) {
const body = result.getBody();
console.log(`Found ${body.found} results (with synonyms)`);
}
}
Error Handling
Comprehensive Error Handling
const { HlqueryException, AuthenticationException, RequestException } = require('./lib/Exceptions');
async function safeOperation() {
try {
const result = await client.createCollection('test', schema);
if (result.isSuccess()) {
console.log('Operation successful');
} else {
console.error('Operation failed:', result.getError());
}
} catch (error) {
if (error instanceof AuthenticationException) {
console.error('Authentication failed. Check your token.');
} else if (error instanceof RequestException) {
console.error('Request failed:', error.message);
console.error('Status code:', error.statusCode);
} else if (error instanceof HlqueryException) {
console.error('hlquery error:', error.message);
} else {
console.error('Unexpected error:', error);
}
}
}
Real-World Scenarios
E-Commerce Product Search
async function ecommerceSearch(userQuery, filters = {}) {
const searchParams = {
q: userQuery,
query_by: 'title,description,tags',
filter_by: buildFilterString(filters),
sort_by: filters.sortBy || 'text_match:desc',
facet_by: 'category,brand,price_range',
limit: 20
};
const result = await client.search('products', searchParams);
if (result.isSuccess()) {
const body = result.getBody();
return {
products: body.hits.map(hit => hit.document),
facets: body.facet_counts,
total: body.found
};
}
return null;
}
function buildFilterString(filters) {
const conditions = [];
if (filters.category) {
conditions.push(`category:${filters.category}`);
}
if (filters.minPrice) {
conditions.push(`price:>=${filters.minPrice}`);
}
if (filters.maxPrice) {
conditions.push(`price:<=${filters.maxPrice}`);
}
if (filters.inStock) {
conditions.push('in_stock:true');
}
return conditions.join(' && ');
}
Content Management System
async function cmsSearch(query, contentType = null) {
const searchParams = {
q: query,
query_by: 'title,content',
limit: 10
};
if (contentType) {
searchParams.filter_by = `type:${contentType}`;
}
const result = await client.search('content', searchParams);
if (result.isSuccess()) {
return result.getBody().hits.map(hit => ({
id: hit.document.id,
title: hit.document.title,
excerpt: hit.document.content.substring(0, 200),
score: hit.text_match
}));
}
return [];
}
Analytics Dashboard
async function getAnalytics() {
const [stats, collections] = await Promise.all([
client.stats(),
client.listCollections(0, 100)
]);
if (stats.isSuccess() && collections.isSuccess()) {
const statsBody = stats.getBody();
const collectionsBody = collections.getBody();
return {
totalCollections: collectionsBody.collections?.length || 0,
totalDocuments: statsBody.documents?.total || 0,
memoryUsage: statsBody.memory,
uptime: statsBody.uptime
};
}
return null;
}
Best Practices
- Always check response status: Use
isSuccess()before accessing response body - Handle errors gracefully: Use try-catch blocks and check for specific exception types
- Use pagination: For large result sets, implement pagination
- Batch operations: Use
import()for bulk document operations - Cache collections: Cache collection schemas to avoid repeated API calls
- Use appropriate timeouts: Set reasonable timeout values for your use case
- Monitor performance: Track response times and error rates
Status Command
The status command provides concise server information:
node example.js status
This will show:
- Health status
- Server statistics
- Protocol codes
- Server status
- Root status response
Next Steps
- API Reference - Complete API documentation
- Tests - Comprehensive test suite
- Main Example:
etc/api/node/example.js- Full example file with all features - Node.js Client Overview