A C++ client library for hlquery with modular APIs, authentication support, HTTPS support, type-safe responses, and basic SAM search helpers.
Build the client and examples locally:
$ cd cpp-api
$ makeOn FreeBSD, use GNU make:
$ cd cpp-api
$ gmakeBuild modes:
# Auto-detect OpenSSL with pkg-config (default)
$ make
# Force HTTP-only build with no OpenSSL dependency
$ make OPENSSL=0
# Require OpenSSL and fail fast if it is not available
$ make OPENSSL=1$ cd cpp-api
$ makeFreeBSD:
$ cd cpp-api
$ gmakeThis will build:
build/libhlqueryclient.a- Static librarybuild/basic_usage- Example executable
All build artifacts are placed in the build/ directory.
To clean build artifacts:
$ make cleanOn FreeBSD:
$ gmake cleanThis removes the entire build/ directory.
On systems where OpenSSL is installed outside the default compiler include path
(for example Homebrew on macOS), the Makefile now pulls both compiler and linker
flags from pkg-config.
#include "hlquery/client.h"
#include <iostream>
int main() {
try {
// Initialize client
hlquery::Client client("http://localhost:9200");
auto collections = client.collections();
auto documents = client.documents();
// Health check
auto health = client.health();
std::cout << "Status: " << health.getStatusCode() << std::endl;
// List collections
auto list = collections->list(0, 10);
if (list.isSuccess()) {
auto body = list.getBody();
// Process collections...
}
auto results = collections->search("products", {
{"like", "laptop"},
{"query_by", "title,content"},
{"limit", "10"}
});
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}// Set token
client.setAuthToken("your_token_here", "bearer");
// Or use API key
client.setAuthToken("your_api_key", "api-key");
// Clear authentication
client.clearAuth();auto collections = client.collections();
// Simple search. "like" is accepted as an alias for "q".
std::map<std::string, std::string> params;
params["like"] = "test";
params["query_by"] = "title,content";
params["limit"] = "10";
auto results = collections->search("collection", params);
// Supported query semantics
// Field-specific search
params["like"] = "title:laptop";
auto field_results = collections->search("collection", params);
// Boolean OR query
params["like"] = "title:laptop OR title:notebook";
auto or_results = collections->search("collection", params);
// Wildcard search
params["like"] = "laptop*";
auto wildcard_results = collections->search("collection", params);
// NOT query
params["like"] = "title:laptop NOT title:refurbished";
auto not_results = collections->search("collection", params);
// Phrase query
params["like"] = "\"wireless keyboard\"";
params["query_by"] = "title";
auto phrase_results = collections->search("collection", params);
// Filter operators belong in filter_by
params["like"] = "*";
params["query_by"] = "title,content";
params["filter_by"] = "price:>100&&category:electronics";
auto filtered_results = collections->search("collection", params);
// SQL search
auto sql_results = client.sql(
"collection",
"SELECT id, title, price FROM collection ORDER BY price DESC LIMIT 5;"
);
std::cout << sql_results.getBody().dump(2) << std::endl;
// Top-level SQL
auto rows = client.sql("SHOW COLLECTIONS;");
auto insert = client.execSql(
"INSERT INTO collection (id, title, price) VALUES ('sku-9', 'Camp Stove', 89);"
);
// Multi-search stays at the client level because it spans multiple collections/queries.
nlohmann::json multi_a = {
{"collection", "products"},
{"q", "laptop"},
{"query_by", "title,content"}
};
nlohmann::json multi_b = {
{"collection", "products"},
{"q", "keyboard"},
{"query_by", "title,content"}
};
auto multi = client.multiSearch({multi_a, multi_b});
// Vector search
std::map<std::string, std::string> vector_params;
vector_params["vector_query"] = "[0.1,0.2,0.3]";
vector_params["limit"] = "5";
auto vector_results = collections->vectorSearch("collection", vector_params);
// Advanced vector search (POST JSON body)
nlohmann::json vector_body = {
{"vector", {0.1, 0.2, 0.3}},
{"field_name", "embedding"},
{"topk", 5},
{"include_distance", true},
{"query_params", {{"ef", 64}, {"nprobe", 4}, {"is_linear", true}}},
{"radius", 1.0}
};
auto advanced = client.executeRequest("POST", "/collections/collection/vector_search", vector_body);
// SAM search
auto sam = client.samSearch("collection", "wireless keyboard");
auto sam_all = client.samSearchAll("guide", {{"limit", "5"}});Preferred structure:
auto collections = client.collections();
auto result = collections->search("products", {{"like", "laptop"}});Compatibility note:
client.searchApi()client.search(...)client.sqlSearch(...)client.vectorSearch(...)
still exist for now, but they are compatibility shims. New code should prefer client.collections()->search(...), client.sql(...), and client.collections()->vectorSearch(...).
SAM search calls /sam/search directly and is useful for broader intent-style lookup.
auto sam = client.samSearch("products", "nineteen");
auto sam_all = client.samSearchAll("benchmark", {{"distributed", "on"}, {"limit", "10"}});auto collections = client.collections();
auto documents = client.documents();
nlohmann::json schema = {
{"fields", nlohmann::json::array({
{{"name", "title"}, {"type", "string"}},
{{"name", "content"}, {"type", "string"}},
{{"name", "price"}, {"type", "float"}}
})}
};
auto created = collections->create("products", schema);
auto updated = collections->update("products", {
{"add_fields", nlohmann::json::array({
{{"name", "brand"}, {"type", "string"}}
})}
});
auto added = documents->add("products", {
{"id", "sku-1"},
{"title", "Laptop Computer"},
{"content", "High-performance laptop with 16GB RAM"},
{"price", 1299.0}
});
auto changed = documents->update("products", "sku-1", {
{"price", 1199.0},
{"brand", "hlquery"}
});
auto removed = documents->remove("products", "sku-1");Quick SQL example:
#include "hlquery/client.h"
#include <iostream>
int main()
{
hlquery::Client client("http://localhost:9200");
auto response = client.sql(
"products",
"SELECT id, title, price FROM products ORDER BY price DESC LIMIT 5;"
);
if (!response.isSuccess())
{
std::cerr << response.getError() << std::endl;
return 1;
}
std::cout << response.getBody().dump(2) << std::endl;
return 0;
}Basic SQL example:
hlquery::Client client("http://localhost:9200");
auto response = client.sql(
"products",
"SELECT id, title, price FROM products ORDER BY price DESC LIMIT 5;"
);
if (response.isSuccess())
{
std::cout << response.getBody().dump(2) << std::endl;
}Top-level SQL execution:
auto rows = client.sql("SHOW COLLECTIONS;");
auto insert = client.execSql(
"INSERT INTO products (id, title, price) VALUES ('sku-9', 'Camp Stove', 89);"
);