Similarity search
Return the closest_n entries most similar to a query vector, ranked by a similarity metric. This is the core vector-search operation.
Every operation works on both Vector DB stores (you supply raw vectors) and AI stores (you supply text or images and Ahnlich AI generates the embeddings for you). Use the Vector DB / AI switch in the sample below.
Parameters
| Parameter | Type | Description |
|---|---|---|
store | string | Name of the store to search. |
search_input | vector | The query vector (StoreKey). Must match the store's dimension. |
closest_n | int (> 0) | How many results to return. |
algorithm | enum | Similarity metric: CosineSimilarity, EuclideanDistance, or DotProductSimilarity. |
condition | predicate · optional | Restrict which vectors are considered. None searches all. See Predicates. |
schema | string · optional | Schema to target. Defaults to public. |
All requests accept an optional
schemafield. When omitted, the server uses thepublicschema.
Behavior
- The server compares the query vector against stored vectors using the chosen metric.
- An optional
conditionnarrows candidates by metadata before ranking. - Results are ordered from most to least similar.
Sample query
- Database engine
- AI proxy
- Python
- Node.js
- Go
- Rust
- CLI
Python
import asyncio
from grpclib.client import Channel
from ahnlich_client_py.grpc.services.db_service import DbServiceStub
from ahnlich_client_py.grpc.db import query as db_query
from ahnlich_client_py.grpc import keyval, predicates
from ahnlich_client_py.grpc.algorithm.algorithms import Algorithm
async def get_simn():
async with Channel(host="127.0.0.1", port=1369) as channel:
client = DbServiceStub(channel)
search_key = keyval.StoreKey(key=[1.0, 2.0, 3.0, 4.0])
response = await client.get_sim_n(
db_query.GetSimN(
store="my_store",
schema="analytics",
search_input=search_key,
closest_n=3,
algorithm=Algorithm.CosineSimilarity,
condition=None # Optional: filter results using predicates
)
)
print(response.entries) # [(key, value, score), ...]
if __name__ == "__main__":
asyncio.run(get_simn())
TypeScript
import { createDbClient } from "ahnlich-client-node";
import { GetSimN } from "ahnlich-client-node/grpc/db/query_pb";
import { StoreKey } from "ahnlich-client-node/grpc/keyval_pb";
import { Algorithm } from "ahnlich-client-node/grpc/algorithm/algorithm_pb";
async function getSimN() {
const client = createDbClient("127.0.0.1:1369");
const response = await client.getSimN(
new GetSimN({
store: "my_store",
schema: "analytics",
searchInput: new StoreKey({ key: [1.0, 2.0, 3.0, 4.0] }),
closestN: 3,
algorithm: Algorithm.COSINE_SIMILARITY,
})
);
console.log(response.entries);
// Iterate over results
for (const entry of response.entries) {
console.log(`Key: ${entry.key?.key}`);
console.log(`Similarity: ${entry.similarity}`);
console.log(`Value: ${JSON.stringify(entry.value?.value)}`);
}
}
getSimN();
Go
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
dbsvc "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/services/db_service"
dbquery "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/db/query"
keyval "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/keyval"
algorithms "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/algorithm/algorithms"
predicates "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/predicates"
)
const ServerAddr = "127.0.0.1:1369"
// ExampleDBClient holds the gRPC connection, client, and context.
func stringPtr(value string) *string { return &value }
type ExampleDBClient struct {
conn *grpc.ClientConn
client dbsvc.DBServiceClient
ctx context.Context
}
// NewDBClient connects to the Ahnlich DB server.
func NewDBClient(ctx context.Context) (*ExampleDBClient, error) {
conn, err := grpc.NewClient(
ServerAddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return nil, fmt.Errorf("failed to dial DB server %q: %w", ServerAddr, err)
}
client := dbsvc.NewDBServiceClient(conn)
return &ExampleDBClient{conn: conn, client: client, ctx: ctx}, nil
}
// Close closes the gRPC connection.
func (c *ExampleDBClient) Close() error {
return c.conn.Close()
}
// -------------------- GetSimN --------------------
func (c *ExampleDBClient) exampleGetSimN() error {
resp, err := c.client.GetSimN(c.ctx, &dbquery.GetSimN{
Store: "my_store",
Schema: stringPtr("analytics"), // Optional: defaults to public when omitted
SearchInput: &keyval.StoreKey{Key: []float32{1, 2, 3, 4}},
ClosestN: 3,
Algorithm: algorithms.Algorithm_CosineSimilarity,
Condition: nil, // Optional: filter results using predicates
})
if err != nil {
return err
}
fmt.Println("GetSimN Results:")
for _, entry := range resp.Entries {
fmt.Println(" - Key:", entry.Key.Key, "Value:", entry.Value.Value)
}
return nil
}
// -------------------- Main --------------------
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := NewDBClient(ctx)
if err != nil {
log.Fatalf("Failed to create DB client: %v", err)
}
defer client.Close()
if err := client.exampleGetSimN(); err != nil {
log.Fatalf("GetSimN failed: %v", err)
}
}
Rust
use ahnlich_client_rs::db::DbClient;
use ahnlich_types::{
algorithm::algorithms::Algorithm,
db::query::GetSimN,
keyval::StoreKey,
};
use tokio;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// connect to server
let addr = "http://127.0.0.1:1369"; // adjust to your server address
let db_client = DbClient::new(addr.to_string()).await?;
// prepare parameters
let params = GetSimN {
store: "my_store".to_string(),
schema: Some("analytics".to_string()),
search_input: Some(StoreKey { key: vec![1.0, 2.0, 3.0, 4.0] }),
closest_n: 2,
algorithm: Algorithm::EuclideanDistance as i32,
condition: None,
};
// call get_sim_n
let response = db_client.get_sim_n(params, None).await?;
println!("Response: {:?}", response);
Ok(())
}
GETSIMN 3 WITH ([1.0, 2.0, 3.0, 4.0]) USING cosinesimilarity IN my_store- Python
- Node.js
- Go
- Rust
- CLI
Python
import asyncio
from grpclib.client import Channel
from ahnlich_client_py.grpc.services.ai_service import AiServiceStub
from ahnlich_client_py.grpc.ai import query as ai_query
from ahnlich_client_py.grpc import keyval
from ahnlich_client_py.grpc.algorithm import algorithms
from ahnlich_client_py.grpc.ai.preprocess import PreprocessAction
async def get_sim_n():
async with Channel(host="127.0.0.1", port=1370) as channel:
client = AiServiceStub(channel)
response = await client.get_sim_n(
ai_query.GetSimN(
store="my_store",
schema="analytics",
search_input=keyval.StoreInput(raw_string="Jordan"),
condition=None, # Optional predicate condition
closest_n=3,
algorithm=algorithms.Algorithm.CosineSimilarity,
preprocess_action=PreprocessAction.ModelPreprocessing, # Apply model's preprocessing
execution_provider=None, # Optional execution provider
model_params={} # Optional: runtime model parameters (e.g., {"confidence_threshold": "0.9"} for face detection)
)
)
# Response contains entries with similarity scores
for entry in response.entries:
print(f"Key: {entry.key.raw_string}")
print(f"Score: {entry.similarity}")
print(f"Value: {entry.value}")
# Key: Jordan One
# Score: Similarity(value=0.858908474445343)
# Value: StoreValue(value={'brand': MetadataValue(raw_string='Nike')})
# Key: Yeezey
# Score: Similarity(value=0.21911849081516266)
# Value: StoreValue(value={'brand': MetadataValue(raw_string='Adidas')})
if __name__ == "__main__":
asyncio.run(get_sim_n())
TypeScript
import { createAiClient } from "ahnlich-client-node";
import { GetSimN } from "ahnlich-client-node/grpc/ai/query_pb";
import { StoreInput } from "ahnlich-client-node/grpc/keyval_pb";
import { Algorithm } from "ahnlich-client-node/grpc/algorithm/algorithm_pb";
async function getSimN() {
const client = createAiClient("127.0.0.1:1370");
const response = await client.getSimN(
new GetSimN({
store: "ai_store",
schema: "analytics",
searchInput: new StoreInput({ value: { case: "rawString", value: "Jordan" } }),
closestN: 3,
algorithm: Algorithm.COSINE_SIMILARITY,
})
);
console.log(response.entries);
for (const entry of response.entries) {
console.log(`Input: ${entry.input?.value}`);
console.log(`Similarity: ${entry.similarity}`);
console.log(`Metadata: ${JSON.stringify(entry.value?.value)}`);
}
}
getSimN();
Go
package main
import (
"context"
"fmt"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
aiquery "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/ai/query"
aisvc "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/services/ai_service"
keyval "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/keyval"
metadata "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/metadata"
algorithms "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/algorithm/algorithms"
preprocess "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/ai/preprocess"
predicates "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/predicates"
)
const AIAddr = "127.0.0.1:1370"
func stringPtr(value string) *string { return &value }
type ExampleAIClient struct {
conn *grpc.ClientConn
client aisvc.AIServiceClient
ctx context.Context
}
func NewAIClient(ctx context.Context) (*ExampleAIClient, error) {
conn, err := grpc.DialContext(ctx, AIAddr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
if err != nil {
return nil, fmt.Errorf("failed to dial AI server %q: %w", AIAddr, err)
}
client := aisvc.NewAIServiceClient(conn)
return &ExampleAIClient{conn: conn, client: client, ctx: ctx}, nil
}
func (c *ExampleAIClient) Close() error {
return c.conn.Close()
}
// Helper to unwrap Key (StoreInput)
func unwrapKey(k *keyval.StoreInput) string {
if k == nil {
return "<nil>"
}
switch v := k.Value.(type) {
case *keyval.StoreInput_RawString:
return v.RawString
default:
return fmt.Sprintf("%v", v)
}
}
// Helper to unwrap Value (StoreValue)
func unwrapValue(v *keyval.StoreValue) map[string]string {
result := make(map[string]string)
if v == nil {
return result
}
for k, val := range v.Value {
switch mv := val.Value.(type) {
case *metadata.MetadataValue_RawString:
result[k] = mv.RawString
default:
result[k] = fmt.Sprintf("%v", mv)
}
}
return result
}
// ---- GetSimN ----
func (c *ExampleAIClient) exampleGetSimNAI() error {
resp, err := c.client.GetSimN(c.ctx, &aiquery.GetSimN{
Store: "ai_store01", // must already exist and have data
Schema: stringPtr("analytics"), // Optional: defaults to public when omitted
SearchInput: &keyval.StoreInput{Value: &keyval.StoreInput_RawString{RawString: "X"}},
Condition: nil, // Optional: filter results using predicates
ClosestN: 3,
Algorithm: algorithms.Algorithm_CosineSimilarity,
PreprocessAction: preprocess.PreprocessAction_ModelPreprocessing, // Apply model's preprocessing
ExecutionProvider: nil, // Optional: e.g., ExecutionProvider_CUDA for GPU acceleration
})
if err != nil {
return err
}
fmt.Println(" AI GetSimN Response:")
for i, entry := range resp.Entries {
fmt.Printf(" #%d Key=%s Value=%v\n", i+1, unwrapKey(entry.Key), unwrapValue(entry.Value))
}
return nil
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
client, err := NewAIClient(ctx)
if err != nil {
log.Fatalf(" Failed to create AI client: %v", err)
}
defer client.Close()
if err := client.exampleGetSimNAI(); err != nil {
log.Fatalf(" GetSimN failed: %v", err)
}
}
Rust
use ahnlich_client_rs::ai::AiClient;
use ahnlich_client_rs::error::AhnlichError;
use ahnlich_types::ai::preprocess::PreprocessAction;
use ahnlich_types::ai::query::GetSimN;
use ahnlich_types::algorithm::algorithms::Algorithm;
use ahnlich_types::keyval::StoreInput;
use ahnlich_types::keyval::store_input::Value;
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), AhnlichError> {
// Connect to AI server
let addr = "127.0.0.1:1370";
let client = AiClient::new(addr.to_string()).await?;
// Prepare the search input
let search_input = StoreInput {
value: Some(Value::RawString("example query".into())),
};
// Construct GetSimN parameters
let params = GetSimN {
store: "Main0".to_string(),
schema: Some("analytics".to_string()),
search_input: Some(search_input),
closest_n: 3, // number of similar entries to retrieve
algorithm: Algorithm::CosineSimilarity as i32,
execution_provider: None,
preprocess_action: PreprocessAction::NoPreprocessing as i32,
condition: None,
model_params: HashMap::new(),
};
// Run the GetSimN command
let res = client.get_sim_n(params, None).await?;
println!("GetSimN result: {:?}", res);
Ok(())
}
GETSIMN 3 WITH [This is a sentence] USING cosinesimilarity IN my_storeResponse
A ranked list of entries, each with its key (vector), value (metadata), and similarity score.