Preview
Preview Feature — This feature is currently in preview and under active development. APIs and functionality may change. We recommend testing thoroughly before using in production.
Querying Vectors
Learn how to search and retrieve vectors from your vector database using similarity search.
Basic Query
Find vectors similar to a query vector:
- TypeScript
- Java
- Go
- .NET
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector, // Array of numbers
topK: 10, // Number of results to return
});
console.log('Matches:', results.matches);
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector, // Array of numbers
"topK", 10, // Number of results to return
));
System.out.println('Matches:', results.matches);
import "context"
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector, // Array of numbers
"topK": 10, // Number of results to return
});
fmt.Println('Matches:', results.matches);
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector, // Array of numbers
["topK"] = 10, // Number of results to return
});
Console.WriteLine('Matches:', results.matches);
Query Options
| Option | Type | Default | Description |
|---|---|---|---|
vector | number[] | Required | Query vector |
topK | number | 10 | Maximum results to return |
filter | object | - | Metadata filter |
includeMetadata | boolean | false | Include metadata in results |
includeValues | boolean | false | Include vector values in results |
namespace | string | 'default' | Namespace to search in |
minScore | number | - | Minimum similarity score threshold |
Including Metadata
Retrieve metadata with results:
- TypeScript
- Java
- Go
- .NET
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 5,
includeMetadata: true,
});
results.matches.forEach((match) => {
console.log(`ID: ${match.id}`);
console.log(`Score: ${match.score}`);
console.log(`Title: ${match.metadata?.title}`);
console.log(`Category: ${match.metadata?.category}`);
});
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 5,
"includeMetadata", true
));
results.matches.forEach((match) => Map.of(
System.out.println(`ID: $Map.of(match.id)`);
System.out.println(`Score: $Map.of(match.score)`);
System.out.println(`Title: $Map.of(match.metadata?.title)`);
System.out.println(`Category: $Map.of(match.metadata?.category)`);
));
import "context"
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 5,
"includeMetadata": true,
});
results.matches.forEach((match) => {
fmt.Println(`ID: ${match.id}`);
fmt.Println(`Score: ${match.score}`);
fmt.Println(`Title: ${match.metadata?.title}`);
fmt.Println(`Category: ${match.metadata?.category}`);
});
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 5,
["includeMetadata"] = true,
});
results.matches.forEach((match) => {
Console.WriteLine(`ID: ${match.id}`);
Console.WriteLine(`Score: ${match.score}`);
Console.WriteLine(`Title: ${match.metadata?.title}`);
Console.WriteLine(`Category: ${match.metadata?.category}`);
});
Filtering Results
Exact Match
- TypeScript
- Java
- Go
- .NET
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
filter: {
category: 'electronics',
},
includeMetadata: true,
});
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
filter: Map.of(
"category", "electronics"
),
"includeMetadata", true
));
import "context"
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
filter: {
"category": "electronics",
},
"includeMetadata": true,
});
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
filter: {
["category"] = "electronics",
},
["includeMetadata"] = true,
});
Multiple Conditions (AND)
- TypeScript
- Java
- Go
- .NET
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
filter: {
category: 'electronics',
in_stock: true,
},
});
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
filter: Map.of(
"category", "electronics",
"in_stock", true
)
));
import "context"
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
filter: {
"category": "electronics",
"in_stock": true,
},
});
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
filter: {
["category"] = "electronics",
["in_stock"] = true,
},
});
Comparison Operators
- TypeScript
- Java
- Go
- .NET
// Price less than 100
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
filter: {
price: { $lt: 100 },
},
});
// Rating greater than or equal to 4
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
filter: {
rating: { $gte: 4 },
},
});
// Price less than 100
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
filter: Map.of(
price: Map.of( $"lt", 100 )
)
));
// Rating greater than or equal to 4
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
filter: Map.of(
rating: Map.of( $"gte", 4 )
)
));
import "context"
// Price less than 100
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
filter: {
price: { $"lt": 100 },
},
});
// Rating greater than or equal to 4
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
filter: {
rating: { $"gte": 4 },
},
});
// Price less than 100
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
filter: {
price: { $["lt"] = 100 },
},
});
// Rating greater than or equal to 4
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
filter: {
rating: { $["gte"] = 4 },
},
});
Available Operators
| Operator | Description | Example |
|---|---|---|
$eq | Equal to | { status: { $eq: 'active' } } |
$ne | Not equal to | { status: { $ne: 'deleted' } } |
$gt | Greater than | { price: { $gt: 50 } } |
$gte | Greater than or equal | { rating: { $gte: 4 } } |
$lt | Less than | { price: { $lt: 100 } } |
$lte | Less than or equal | { quantity: { $lte: 10 } } |
$in | In array | { category: { $in: ['books', 'media'] } } |
$nin | Not in array | { status: { $nin: ['deleted', 'archived'] } } |
Complex Filters
- TypeScript
- Java
- Go
- .NET
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
filter: {
$and: [
{ category: 'electronics' },
{ price: { $lt: 500 } },
{ rating: { $gte: 4 } },
],
},
});
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
filter: {
$or: [
{ category: 'electronics' },
{ category: 'computers' },
],
},
});
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
filter: Map.of(
$and: [
Map.of( "category", "electronics" ),
Map.of( price: Map.of( $"lt", 500 ) ),
Map.of( rating: Map.of( $"gte", 4 ) ),
]
)
));
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
filter: Map.of(
$or: [
Map.of( "category", "electronics" ),
Map.of( "category", "computers" ),
]
)
));
import "context"
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
filter: {
$and: [
{ "category": "electronics" },
{ price: { $"lt": 500 } },
{ rating: { $"gte": 4 } },
],
},
});
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
filter: {
$or: [
{ "category": "electronics" },
{ "category": "computers" },
],
},
});
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
filter: {
$and: [
{ ["category"] = "electronics" },
{ price: { $["lt"] = 500 } },
{ rating: { $["gte"] = 4 } },
],
},
});
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
filter: {
$or: [
{ ["category"] = "electronics" },
{ ["category"] = "computers" },
],
},
});
Minimum Score Threshold
Only return results above a similarity threshold:
- TypeScript
- Java
- Go
- .NET
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
minScore: 0.7, // Only results with 70%+ similarity
includeMetadata: true,
});
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
"minScore", 0.7, // Only results with 70%+ similarity
"includeMetadata", true
));
import "context"
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
"minScore": 0.7, // Only results with 70%+ similarity
"includeMetadata": true,
});
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
["minScore"] = 0.7, // Only results with 70%+ similarity
["includeMetadata"] = true,
});
Namespaces
Query within a specific namespace:
- TypeScript
- Java
- Go
- .NET
// Query in 'products' namespace
const productResults = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
namespace: 'products',
});
// Query in 'articles' namespace
const articleResults = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 10,
namespace: 'articles',
});
// Query in 'products' namespace
Map<String, Object> productResults = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
"namespace", "products"
));
// Query in 'articles' namespace
Map<String, Object> articleResults = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 10,
"namespace", "articles"
));
import "context"
// Query in 'products' namespace
productResults := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
"namespace": "products",
});
// Query in 'articles' namespace
articleResults := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 10,
"namespace": "articles",
});
// Query in 'products' namespace
var productResults = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
["namespace"] = "products",
});
// Query in 'articles' namespace
var articleResults = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 10,
["namespace"] = "articles",
});
Understanding Similarity Scores
Scores depend on your distance metric:
Cosine Similarity
- Range: 0 to 1 (higher is more similar)
- 1.0 = identical direction
- 0.0 = orthogonal (unrelated)
Euclidean Distance
- Range: 0 to infinity (lower is more similar)
- 0.0 = identical
- Results often converted to similarity score
Dot Product
- Range: varies (higher is more similar)
- Best with normalized vectors
Query Patterns
Semantic Search
- TypeScript
- Java
- Go
- .NET
async function semanticSearch(query: string, limit: number = 10) {
const queryVector = await getEmbedding(query);
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: limit,
includeMetadata: true,
});
return results.matches.map((match) => ({
id: match.id,
score: match.score,
content: match.metadata?.content,
}));
}
const articles = await semanticSearch('machine learning tutorials');
async function semanticSearch(query: string, limit: number = 10) Map.of(
Map<String, Object> queryVector = getEmbedding(query);
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
topK: limit,
"includeMetadata", true
));
return results.matches.map((match) => (Map.of(
id: match.id,
score: match.score,
content: match.metadata?.content
)));
)
Map<String, Object> articles = semanticSearch('machine learning tutorials');
import "context"
async function semanticSearch(query: string, limit: number = 10) {
queryVector := getEmbedding(query);
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
topK: limit,
"includeMetadata": true,
});
return results.matches.map((match) => ({
id: match.id,
score: match.score,
content: match.metadata?.content,
}));
}
articles := semanticSearch('machine learning tutorials');
async function semanticSearch(query: string, limit: number = 10) {
var queryVector = await getEmbedding(query);
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
topK: limit,
["includeMetadata"] = true,
});
return results.matches.map((match) => ({
id: match.id,
score: match.score,
content: match.metadata?.content,
}));
}
var articles = await semanticSearch('machine learning tutorials');
Find Similar Items
- TypeScript
- Java
- Go
- .NET
async function findSimilar(itemId: string, limit: number = 5) {
// Fetch the item's vector
const item = await ductape.vector.fetchVectors({
tag: 'my-vectors',
ids: [itemId],
});
const vector = item.vectors[itemId].values;
// Query for similar items, excluding the original
const results = await ductape.vector.query({
tag: 'my-vectors',
vector,
topK: limit + 1, // +1 to account for the item itself
includeMetadata: true,
});
// Filter out the original item
return results.matches
.filter((match) => match.id !== itemId)
.slice(0, limit);
}
const similarProducts = await findSimilar('prod-123');
async function findSimilar(itemId: string, limit: number = 5) Map.of(
// Fetch the item's vector
Map<String, Object> item = ductape.vector.fetchVectors(Map.of(
"tag", "my-vectors",
ids: [itemId]
));
Map<String, Object> vector = item.vectors[itemId].values;
// Query for similar items, excluding the original
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector,
topK: limit + 1, // +1 to account for the item itself
"includeMetadata", true
));
// Filter out the original item
return results.matches
.filter((match) => match.id !== itemId)
.slice(0, limit);
)
Map<String, Object> similarProducts = findSimilar('prod-123');
import "context"
async function findSimilar(itemId: string, limit: number = 5) {
// Fetch the item's vector
item := client.vector.fetchVectors({
"tag": "my-vectors",
ids: [itemId],
});
vector := item.vectors[itemId].values;
// Query for similar items, excluding the original
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector,
topK: limit + 1, // +1 to account for the item itself
"includeMetadata": true,
});
// Filter out the original item
return results.matches
.filter((match) => match.id !== itemId)
.slice(0, limit);
}
similarProducts := findSimilar('prod-123');
async function findSimilar(itemId: string, limit: number = 5) {
// Fetch the item's vector
var item = await ductape.vector.fetchVectors({
["tag"] = "my-vectors",
ids: [itemId],
});
var vector = item.vectors[itemId].values;
// Query for similar items, excluding the original
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector,
topK: limit + 1, // +1 to account for the item itself
["includeMetadata"] = true,
});
// Filter out the original item
return results.matches
.filter((match) => match.id !== itemId)
.slice(0, limit);
}
var similarProducts = await findSimilar('prod-123');
Hybrid Search
Combine vector similarity with metadata filters:
- TypeScript
- Java
- Go
- .NET
async function hybridSearch(
query: string,
category: string,
priceRange: { min: number; max: number }
) {
const queryVector = await getEmbedding(query);
const results = await ductape.vector.query({
tag: 'my-vectors',
vector: queryVector,
topK: 20,
filter: {
category,
price: {
$gte: priceRange.min,
$lte: priceRange.max,
},
},
includeMetadata: true,
});
return results.matches;
}
const products = await hybridSearch(
'wireless headphones',
'electronics',
{ min: 50, max: 200 }
);
async function hybridSearch(
query: string,
category: string,
priceRange: Map.of( min: number; max: number )
) Map.of(
Map<String, Object> queryVector = getEmbedding(query);
Map<String, Object> results = ductape.vectors().query(Map<String, Object>.of(
"tag", "my-vectors",
vector: queryVector,
"topK", 20,
filter: Map.of(
category,
price: Map.of(
$gte: priceRange.min,
$lte: priceRange.max
)
),
"includeMetadata", true
));
return results.matches;
)
Map<String, Object> products = hybridSearch(
'wireless headphones',
'electronics',
Map.of( "min", 50, "max", 200 )
);
import "context"
async function hybridSearch(
query: string,
category: string,
priceRange: { min: number; max: number }
) {
queryVector := getEmbedding(query);
results := client.VectorAPI.Query(ctx, map[string]any{
"tag": "my-vectors",
vector: queryVector,
"topK": 20,
filter: {
category,
price: {
$gte: priceRange.min,
$lte: priceRange.max,
},
},
"includeMetadata": true,
});
return results.matches;
}
products := hybridSearch(
'wireless headphones',
'electronics',
{ "min": 50, "max": 200 }
);
async function hybridSearch(
query: string,
category: string,
priceRange: { min: number; max: number }
) {
var queryVector = await getEmbedding(query);
var results = await ductape.Vector.Query(new Dictionary<string, object?>
{
["tag"] = "my-vectors",
vector: queryVector,
["topK"] = 20,
filter: {
category,
price: {
$gte: priceRange.min,
$lte: priceRange.max,
},
},
["includeMetadata"] = true,
});
return results.matches;
}
var products = await hybridSearch(
'wireless headphones',
'electronics',
{ ["min"] = 50, ["max"] = 200 }
);
Next Steps
- Metadata Filtering - Advanced filtering patterns
- Using with Agents - Connect vectors to AI agents
- Best Practices - Optimization tips