A modular Perl client library for hlquery, designed with a familiar and intuitive API structure.
- Modular Architecture: Clean separation of concerns with organized classes
- Intuitive API: Familiar and easy-to-use structure
- Authentication Support: Bearer token and X-API-Key authentication
- Flexible Parameters: Support for multiple parameter formats
- Auto-detection: Automatically detects searchable fields when not specified
- Type-safe Responses: Response objects with helper methods
- Comprehensive Validation: Input validation for all operations
- Minimal Dependencies: Uses standard Perl modules (LWP, JSON, URI)
Install required Perl modules:
cpanm LWP::UserAgent JSON URI URI::Escape Digest::MD5Or using cpanfile:
cpanm --installdeps .Add the lib directory to your Perl path:
$ use lib '/path/to/hlquery/etc/api/perl/lib';
$ use Hlquery::Client;Use the canonical Hlquery::Client, Hlquery::Collections, Hlquery::Documents,
Hlquery::Request, Hlquery::Response, and Hlquery::Search module names. Lowercase
imports such as Hlquery::client are no longer supported as direct file-based imports
because they create release tarball collisions on case-insensitive filesystems.
use Hlquery::Client;
# Initialize client
my $client = Hlquery::Client->new('http://localhost:9200');
# Health check
my $health = $client->Health();
print "Status: " . $health->GetStatusCode() . "\n";
# List collections
my $collections = $client->ListCollections(0, 10);
if ($collections->IsSuccess()) {
my $body = $collections->GetBody();
print "Found " . scalar(@{$body->{collections}}) . " collections\n";
}# Method 1: Set token in constructor
my $client = Hlquery::Client->new('http://localhost:9200', {
token => 'your_token_here',
auth_method => 'bearer' # or 'api-key'
});
# Method 2: Set token dynamically
my $client = Hlquery::Client->new('http://localhost:9200');
$client->SetAuthToken('your_token_here', 'bearer');
# Method 3: Use X-API-Key
$client->SetAuthToken('your_token_here', 'api-key');If the ai_search module is enabled, you can use the raw request helper to summarize a stored document:
my $summary = $client->ExecuteRequest(
'GET',
'/modules/ai_search/talk',
undef,
{
q => 'summarize onboarding guide in docs',
run => 'true',
}
);
print $summary->GetRawBody() . "\n";Main client class that provides access to all API operations.
Handles HTTP requests, authentication, and error handling using LWP::UserAgent.
Response wrapper with helper methods:
GetStatusCode()- Get HTTP status codeGetBody()- Get response bodyGetData()- Get 'data' field from response bodyIsSuccess()- Check if request was successfulIsError()- Check if request failedGetError()- Get error messageToHash()- Convert to hash format (for backward compatibility)
Hlquery::Collections manages collections (List, Get, Create, Delete, Update).
Hlquery::Documents handles document CRUD plus ImportDocuments.
Hlquery::Search covers search requests and parameter normalization.
Hlquery::Utils::Auth handles token helpers and validation.
Hlquery::Utils::Config provides defaults and URL/config parsing.
Hlquery::Utils::Validator validates client input before requests are sent.
Hlquery::Exception is the base type.
Use Hlquery::AuthenticationException, Hlquery::RequestException, Hlquery::ValidationException, Hlquery::CollectionException, Hlquery::DocumentException, and Hlquery::SearchException for more specific failures.
Check server health status.
my $health = $client->Health();
if ($health->IsSuccess()) {
my $body = $health->GetBody();
print "Status: " . $body->{status} . "\n";
}Get server statistics.
my $stats = $client->Stats();Get server information.
my $info = $client->Info();my $collections = $client->Collections();
# List collections
my $result = $collections->List(0, 10);
# Get collection
$result = $collections->Get('my_collection');
# Create collection
$result = $collections->Create('new_collection', $schema);
# Delete collection
$result = $collections->Delete('collection_name');
# Get formatted fields
$result = $collections->GetFields('my_collection');# List collections
my $collections = $client->ListCollections(0, 10);
# Get collection details
my $collection = $client->GetCollection('my_collection');
# Get collection fields (formatted)
my $fields = $client->GetCollectionFields('my_collection');my $documents = $client->Documents();
# List documents
my $result = $documents->List('collection', { offset => 0, limit => 10 });
# Get document
$result = $documents->Get('collection', 'doc_id');
# Add document
$result = $documents->Add('collection', $document);
# Update document
$result = $documents->Update('collection', 'doc_id', $document);
# Delete document
$result = $documents->Delete('collection', 'doc_id');
# Bulk import
$result = $documents->ImportDocuments('collection', [$doc1, $doc2, $doc3]);# List documents
my $docs = $client->ListDocuments('collection', { offset => 0, limit => 10 });
# Get document
my $doc = $client->GetDocument('collection', 'doc_id');my $search = $client->SearchAPI();
# Simple search
my $results = $search->Search('collection', {
q => 'search query',
query_by => 'title,content',
limit => 10
});
# Multi-search
$results = $search->MultiSearch([
{ collection => 'col1', q => 'query1' },
{ collection => 'col2', q => 'query2' }
]);
# Vector search (POST body)
my $vector_results = $search->VectorSearch('collection', {
body => {
vector => [0.1, 0.2, 0.3],
field_name => 'embedding',
topk => 5,
include_distance => JSON::true,
query_params => { ef => 128, nprobe => 8, is_linear => JSON::true }
}
});# Search documents
my $results = $client->Search('collection', {
q => 'search query',
query_by => 'title,content',
limit => 10
});The Search() method accepts flexible parameters:
The q parameter supports the current lexical query syntax:
- FIELD:
q => 'title:laptop' - NOT:
q => 'title:laptop NOT title:refurbished'orq => 'NOT apple' - Boolean:
q => 'title:laptop OR title:notebook' - WILDCARD:
q => 'laptop*',q => '*laptop',q => 'lap*top' - Phrase:
q => '"exact phrase"'
Use filter_by for field filters and numeric comparisons, for example:
filter_by => 'price:>100&&category:electronics'filter_by => 'category:food||category:nature'
query_by- Fields to search in (comma-separated string or array reference)query- Structured query object
from/offset- Starting offsetsize/limit- Number of resultspage- Page number (alternative to offset)per_page- Results per page
filter_by- Filter conditions (string)filter- Filter objectsort_by- Sort fields (string or array reference)sort- Sort specification
facet_by- Facet fields (string or array reference)facets- Facet specification
Alias for ListCollections().
my $collections = $client->Indices({ offset => 0, limit => 10 });Alias for GetCollection() or GetDocument().
# Get document
my $doc = $client->Get({ index => 'collection', id => 'doc_id' });
# Get collection
my $collection = $client->Get({ index => 'collection' });Cat API for listing collections and system information.
my $indices = $client->Cat('indices', { limit => 10 });All methods return a Hlquery::Response object:
my $response = $client->Health();
# Check status
if ($response->IsSuccess()) {
# Handle success
my $body = $response->GetBody();
}
# Or check status code
if ($response->GetStatusCode() == 200) {
# Handle success
}
# Get error
if ($response->IsError()) {
my $error = $response->GetError();
print "Error: $error\n";
}
# Convert to hash (for backward compatibility)
my $hash = $response->ToHash();
# Returns: { status => 200, body => {...} }See example.pl for a complete example demonstrating:
- Health checks
- Authentication (with and without token)
- Listing collections
- Getting collection fields
- Listing documents with pagination
- Multiple search methods
- Dynamic authentication
Run the example:
# Without authentication
perl example.pl
# With authentication
perl example.pl your_token_hereCheck the examples/ directory for organized examples:
basic_usage.pl- Basic operationssearch.pl- Search patternscollections.pl- Collection managementdocuments.pl- Document CRUD
- Perl >= 5.10
- LWP::UserAgent - For HTTP requests
- JSON - For JSON encoding/decoding
- URI - For URL handling
- URI::Escape - For URL encoding
- Digest::MD5 - For token generation
