Querying Data
Learn how to read data from your database using Ductape's query API. This guide covers filtering, sorting, pagination, relationships, and advanced query patterns.
Quick Example
- TypeScript
- Java
- Go
- .NET
const users = await ductape.database.query({
table: 'users',
where: { status: 'active' },
orderBy: { column: 'created_at', order: 'DESC' },
limit: 10,
});
console.log('Active users:', users.data);
console.log('Total count:', users.count);
Map<String, Object> users = ductape.database.query(Map.of(
"table", "users",
where: Map.of( "status", "active" ),
orderBy: Map.of( "column", "created_at", "order", "DESC" ),
"limit", 10
));
System.out.println('Active "users", ", users.data);
System.out.println("Total count:', users.count);
users := client.database.query({
"table": "users",
where: { "status": "active" },
orderBy: { "column": "created_at", "order": "DESC" },
"limit": 10,
});
fmt.Println('Active "users": ", users.data);
fmt.Println("Total count:', users.count);
var users = await ductape.database.query({
["table"] = "users",
where: { ["status"] = "active" },
orderBy: { ["column"] = "created_at", ["order"] = "DESC" },
["limit"] = 10,
});
Console.WriteLine('Active ["users"] = ", users.data);
Console.WriteLine("Total count:', users.count);
Basic Queries
Simple Query
Fetch all records from a table:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users"
));
result := client.database.query({
"table": "users",
});
var result = await ductape.database.query({
["table"] = "users",
});
Query with Connection Parameters
If you haven't called connect(), specify the connection:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
database: 'users-db',
table: 'users',
});
Map<String, Object> result = ductape.database.query(Map.of(
"database", "users-db",
"table", "users"
));
result := client.database.query({
"database": "users-db",
"table": "users",
});
var result = await ductape.database.query({
["database"] = "users-db",
["table"] = "users",
});
Select Specific Columns
Fetch only the columns you need:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
select: ['id', 'email', 'name', 'created_at'],
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
select: ['id', 'email', 'name', 'created_at']
));
result := client.database.query({
"table": "users",
select: ['id', 'email', 'name', 'created_at'],
});
var result = await ductape.database.query({
["table"] = "users",
select: ['id', 'email', 'name', 'created_at'],
});
Filtering with WHERE
Simple Equality
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: {
status: 'active',
role: 'admin',
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
"status", "active",
"role", "admin"
)
));
result := client.database.query({
"table": "users",
where: {
"status": "active",
"role": "admin",
},
});
var result = await ductape.database.query({
["table"] = "users",
where: {
["status"] = "active",
["role"] = "admin",
},
});
Comparison Operators
Use $-prefixed operators for advanced filtering. Ductape uses lowercase operators following the Mongoose/MongoDB convention for familiarity:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'products',
where: {
price: { $gt: 10 }, // Greater than
stock: { $gte: 5 }, // Greater than or equal
discount: { $lt: 50 }, // Less than
rating: { $lte: 4.5 }, // Less than or equal
status: { $ne: 'deleted' }, // Not equal
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "products",
where: Map.of(
price: Map.of( $"gt", 10 ), // Greater than
stock: Map.of( $"gte", 5 ), // Greater than or equal
discount: Map.of( $"lt", 50 ), // Less than
rating: Map.of( $"lte", 4.5 ), // Less than or equal
status: Map.of( $"ne", "deleted" ), // Not equal
)
));
result := client.database.query({
"table": "products",
where: {
price: { $"gt": 10 }, // Greater than
stock: { $"gte": 5 }, // Greater than or equal
discount: { $"lt": 50 }, // Less than
rating: { $"lte": 4.5 }, // Less than or equal
status: { $"ne": "deleted" }, // Not equal
},
});
var result = await ductape.database.query({
["table"] = "products",
where: {
price: { $["gt"] = 10 }, // Greater than
stock: { $["gte"] = 5 }, // Greater than or equal
discount: { $["lt"] = 50 }, // Less than
rating: { $["lte"] = 4.5 }, // Less than or equal
status: { $["ne"] = "deleted" }, // Not equal
},
});
Available Operators
| Operator | Description | Example |
|---|---|---|
$gt | Greater than | { age: { $gt: 18 } } |
$gte | Greater than or equal | { age: { $gte: 18 } } |
$lt | Less than | { price: { $lt: 100 } } |
$lte | Less than or equal | { price: { $lte: 100 } } |
$ne | Not equal | { status: { $ne: 'deleted' } } |
$in | In array | { status: { $in: ['active', 'pending'] } } |
$nin | Not in array | { status: { $nin: ['deleted', 'banned'] } } |
$like | Pattern match | { email: { $like: '%@gmail.com' } } |
$isNull | Is null | { deleted_at: { $isNull: true } } |
$isNotNull | Is not null | { verified_at: { $isNotNull: true } } |
$between | Between values | { created_at: { $between: [start, end] } } |
$regex | Regex match | { email: { $regex: '^user.*@example.com$' } } |
$exists | Property exists | { avatar: { $exists: true } } |
Uppercase operators (e.g., $GT, $IN) are still supported for backwards compatibility, but lowercase is recommended.
IN Operator
Match any value in an array:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'orders',
where: {
status: { $in: ['pending', 'processing', 'shipped'] },
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "orders",
where: Map.of(
status: Map.of( $in: ['pending', 'processing', 'shipped'] )
)
));
result := client.database.query({
"table": "orders",
where: {
status: { $in: ['pending', 'processing', 'shipped'] },
},
});
var result = await ductape.database.query({
["table"] = "orders",
where: {
status: { $in: ['pending', 'processing', 'shipped'] },
},
});
Pattern Matching (LIKE)
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: {
email: { $like: '%@gmail.com' },
name: { $like: 'John%' },
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
email: Map.of( $"like", "%@gmail.com" ),
name: Map.of( $"like", "John%" )
)
));
result := client.database.query({
"table": "users",
where: {
email: { $"like": "%@gmail.com" },
name: { $"like": "John%" },
},
});
var result = await ductape.database.query({
["table"] = "users",
where: {
email: { $["like"] = "%@gmail.com" },
name: { $["like"] = "John%" },
},
});
NULL Checks
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: {
deleted_at: { $isNull: true }, // Not deleted
verified_at: { $isNotNull: true }, // Verified
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
deleted_at: Map.of( $"isNull", true ), // Not deleted
verified_at: Map.of( $"isNotNull", true ), // Verified
)
));
result := client.database.query({
"table": "users",
where: {
deleted_at: { $"isNull": true }, // Not deleted
verified_at: { $"isNotNull": true }, // Verified
},
});
var result = await ductape.database.query({
["table"] = "users",
where: {
deleted_at: { $["isNull"] = true }, // Not deleted
verified_at: { $["isNotNull"] = true }, // Verified
},
});
BETWEEN
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'orders',
where: {
created_at: {
$between: [new Date('2024-01-01'), new Date('2024-12-31')],
},
total: { $between: [100, 500] },
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "orders",
where: Map.of(
created_at: Map.of(
$between: [new Date('2024-01-01'), new Date('2024-12-31')]
),
total: Map.of( $between: [100, 500] )
)
));
result := client.database.query({
"table": "orders",
where: {
created_at: {
$between: [new Date('2024-01-01'), new Date('2024-12-31')],
},
total: { $between: [100, 500] },
},
});
var result = await ductape.database.query({
["table"] = "orders",
where: {
created_at: {
$between: [new Date('2024-01-01'), new Date('2024-12-31')],
},
total: { $between: [100, 500] },
},
});
Logical Operators
Logical operators support both object syntax and array syntax (Mongoose-style):
AND Conditions
All conditions must match:
- TypeScript
- Java
- Go
- .NET
// Object syntax
const result = await ductape.database.query({
table: 'products',
where: {
$and: {
price: { $gte: 10, $lte: 100 },
category: { $in: ['electronics', 'gadgets'] },
stock: { $gt: 0 },
deleted_at: { $isNull: true },
},
},
});
// Array syntax (Mongoose-style)
const result2 = await ductape.database.query({
table: 'products',
where: {
$and: [
{ price: { $gte: 10 } },
{ price: { $lte: 100 } },
{ category: { $in: ['electronics', 'gadgets'] } },
],
},
});
// Object syntax
Map<String, Object> result = ductape.database.query(Map.of(
"table", "products",
where: Map.of(
$and: Map.of(
price: Map.of( $"gte", 10, $"lte", 100 ),
category: Map.of( $in: ['electronics', 'gadgets'] ),
stock: Map.of( $"gt", 0 ),
deleted_at: Map.of( $"isNull", true )
)
)
));
// Array syntax (Mongoose-style)
Map<String, Object> result2 = ductape.database.query(Map.of(
"table", "products",
where: Map.of(
$and: [
Map.of( price: Map.of( $"gte", 10 ) ),
Map.of( price: Map.of( $"lte", 100 ) ),
Map.of( category: Map.of( $in: ['electronics', 'gadgets'] ) ),
]
)
));
// Object syntax
result := client.database.query({
"table": "products",
where: {
$and: {
price: { $"gte": 10, $"lte": 100 },
category: { $in: ['electronics', 'gadgets'] },
stock: { $"gt": 0 },
deleted_at: { $"isNull": true },
},
},
});
// Array syntax (Mongoose-style)
result2 := client.database.query({
"table": "products",
where: {
$and: [
{ price: { $"gte": 10 } },
{ price: { $"lte": 100 } },
{ category: { $in: ['electronics', 'gadgets'] } },
],
},
});
// Object syntax
var result = await ductape.database.query({
["table"] = "products",
where: {
$and: {
price: { $["gte"] = 10, $["lte"] = 100 },
category: { $in: ['electronics', 'gadgets'] },
stock: { $["gt"] = 0 },
deleted_at: { $["isNull"] = true },
},
},
});
// Array syntax (Mongoose-style)
var result2 = await ductape.database.query({
["table"] = "products",
where: {
$and: [
{ price: { $["gte"] = 10 } },
{ price: { $["lte"] = 100 } },
{ category: { $in: ['electronics', 'gadgets'] } },
],
},
});
OR Conditions
Any condition can match:
- TypeScript
- Java
- Go
- .NET
// Object syntax
const result = await ductape.database.query({
table: 'users',
where: {
$or: {
role: 'admin',
is_superuser: true,
},
},
});
// Array syntax (Mongoose-style)
const result2 = await ductape.database.query({
table: 'users',
where: {
$or: [
{ role: 'admin' },
{ is_superuser: true },
],
},
});
// Object syntax
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
$or: Map.of(
"role", "admin",
"is_superuser", true
)
)
));
// Array syntax (Mongoose-style)
Map<String, Object> result2 = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
$or: [
Map.of( "role", "admin" ),
Map.of( "is_superuser", true ),
]
)
));
// Object syntax
result := client.database.query({
"table": "users",
where: {
$or: {
"role": "admin",
"is_superuser": true,
},
},
});
// Array syntax (Mongoose-style)
result2 := client.database.query({
"table": "users",
where: {
$or: [
{ "role": "admin" },
{ "is_superuser": true },
],
},
});
// Object syntax
var result = await ductape.database.query({
["table"] = "users",
where: {
$or: {
["role"] = "admin",
["is_superuser"] = true,
},
},
});
// Array syntax (Mongoose-style)
var result2 = await ductape.database.query({
["table"] = "users",
where: {
$or: [
{ ["role"] = "admin" },
{ ["is_superuser"] = true },
],
},
});
Nested AND/OR
Combine AND and OR for complex queries:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'orders',
where: {
$and: [
{ total: { $gt: 100 } },
{ status: { $in: ['pending', 'processing'] } },
{
$or: [
{ priority: 'high' },
{ express_shipping: true },
],
},
],
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "orders",
where: Map.of(
$and: [
Map.of( total: Map.of( $"gt", 100 ) ),
Map.of( status: Map.of( $in: ['pending', 'processing'] ) ),
Map.of(
$or: [
Map.of( "priority", "high" ),
Map.of( "express_shipping", true ),
]
),
]
)
));
result := client.database.query({
"table": "orders",
where: {
$and: [
{ total: { $"gt": 100 } },
{ status: { $in: ['pending', 'processing'] } },
{
$or: [
{ "priority": "high" },
{ "express_shipping": true },
],
},
],
},
});
var result = await ductape.database.query({
["table"] = "orders",
where: {
$and: [
{ total: { $["gt"] = 100 } },
{ status: { $in: ['pending', 'processing'] } },
{
$or: [
{ ["priority"] = "high" },
{ ["express_shipping"] = true },
],
},
],
},
});
NOR Conditions
None of the conditions should match:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: {
$nor: [
{ status: 'banned' },
{ status: 'suspended' },
],
},
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
$nor: [
Map.of( "status", "banned" ),
Map.of( "status", "suspended" ),
]
)
));
result := client.database.query({
"table": "users",
where: {
$nor: [
{ "status": "banned" },
{ "status": "suspended" },
],
},
});
var result = await ductape.database.query({
["table"] = "users",
where: {
$nor: [
{ ["status"] = "banned" },
{ ["status"] = "suspended" },
],
},
});
Sorting
Single Column Sort
- TypeScript
- Java
- Go
- .NET
import { SortOrder } from '@ductape/sdk';
const result = await ductape.database.query({
table: 'users',
orderBy: { column: 'created_at', order: SortOrder.DESC },
});
import Map.of( SortOrder ) from '@ductape/sdk';
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
orderBy: Map.of( "column", "created_at", order: SortOrder.DESC )
));
import { SortOrder } from '@ductape/sdk';
result := client.database.query({
"table": "users",
orderBy: { "column": "created_at", order: SortOrder.DESC },
});
import { SortOrder } from '@ductape/sdk';
var result = await ductape.database.query({
["table"] = "users",
orderBy: { ["column"] = "created_at", order: SortOrder.DESC },
});
Multiple Column Sort
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'products',
orderBy: [
{ column: 'category', order: 'ASC' },
{ column: 'price', order: 'DESC' },
],
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "products",
orderBy: [
Map.of( "column", "category", "order", "ASC" ),
Map.of( "column", "price", "order", "DESC" ),
]
));
result := client.database.query({
"table": "products",
orderBy: [
{ "column": "category", "order": "ASC" },
{ "column": "price", "order": "DESC" },
],
});
var result = await ductape.database.query({
["table"] = "products",
orderBy: [
{ ["column"] = "category", ["order"] = "ASC" },
{ ["column"] = "price", ["order"] = "DESC" },
],
});
Pagination
Limit and Offset
- TypeScript
- Java
- Go
- .NET
const page = 1;
const pageSize = 20;
const result = await ductape.database.query({
table: 'users',
limit: pageSize,
offset: (page - 1) * pageSize,
});
console.log('Page data:', result.data);
console.log('Total records:', result.count);
console.log('Total pages:', Math.ceil(result.count / pageSize));
Map<String, Object> page = 1;
Map<String, Object> pageSize = 20;
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
limit: pageSize,
offset: (page - 1) * pageSize
));
System.out.println('Page "data", ", result.data);
System.out.println("Total "records", ", result.count);
System.out.println("Total pages:', Math.ceil(result.count / pageSize));
page := 1;
pageSize := 20;
result := client.database.query({
"table": "users",
limit: pageSize,
offset: (page - 1) * pageSize,
});
fmt.Println('Page "data": ", result.data);
fmt.Println("Total "records": ", result.count);
fmt.Println("Total pages:', Math.ceil(result.count / pageSize));
var page = 1;
var pageSize = 20;
var result = await ductape.database.query({
["table"] = "users",
limit: pageSize,
offset: (page - 1) * pageSize,
});
Console.WriteLine('Page ["data"] = ", result.data);
Console.WriteLine("Total ["records"] = ", result.count);
Console.WriteLine("Total pages:', Math.ceil(result.count / pageSize));
Relationships (Include)
Fetch related data in a single query using the include option.
Many-to-One Relationship
Fetch a record with its related parent:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: { id: 1 },
include: {
relation: 'profile',
type: 'many-to-one',
foreignKey: 'profile_id',
primaryKey: 'id',
select: ['bio', 'avatar_url'],
},
});
// Result:
// {
// id: 1,
// name: 'John Doe',
// email: 'john@example.com',
// profile: { bio: '...', avatar_url: '...' }
// }
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of( "id", 1 ),
include: Map.of(
"relation", "profile",
"type", "many-to-one",
"foreignKey", "profile_id",
"primaryKey", "id",
select: ['bio', 'avatar_url']
)
));
// Result:
// Map.of(
// "id", 1,
// "name", "John Doe",
// "email", "john@example.com",
// profile: Map.of( "bio", "...", "avatar_url", "..." )
// )
result := client.database.query({
"table": "users",
where: { "id": 1 },
include: {
"relation": "profile",
"type": "many-to-one",
"foreignKey": "profile_id",
"primaryKey": "id",
select: ['bio', 'avatar_url'],
},
});
// Result:
// {
// "id": 1,
// "name": "John Doe",
// "email": "john@example.com",
// profile: { "bio": "...", "avatar_url": "..." }
// }
var result = await ductape.database.query({
["table"] = "users",
where: { ["id"] = 1 },
include: {
["relation"] = "profile",
["type"] = "many-to-one",
["foreignKey"] = "profile_id",
["primaryKey"] = "id",
select: ['bio', 'avatar_url'],
},
});
// Result:
// {
// ["id"] = 1,
// ["name"] = "John Doe",
// ["email"] = "john@example.com",
// profile: { ["bio"] = "...", ["avatar_url"] = "..." }
// }
One-to-Many Relationship
Fetch a record with its related children:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: { id: 1 },
include: {
relation: 'posts',
type: 'one-to-many',
foreignKey: 'user_id',
primaryKey: 'id',
select: ['id', 'title', 'created_at'],
where: { published: true },
orderBy: { column: 'created_at', order: 'DESC' },
limit: 10,
},
});
// Result:
// {
// id: 1,
// name: 'John Doe',
// posts: [
// { id: 1, title: 'First Post', created_at: '...' },
// { id: 2, title: 'Second Post', created_at: '...' },
// ]
// }
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of( "id", 1 ),
include: Map.of(
"relation", "posts",
"type", "one-to-many",
"foreignKey", "user_id",
"primaryKey", "id",
select: ['id', 'title', 'created_at'],
where: Map.of( "published", true ),
orderBy: Map.of( "column", "created_at", "order", "DESC" ),
"limit", 10
)
));
// Result:
// Map.of(
// "id", 1,
// "name", "John Doe",
// posts: [
// Map.of( "id", 1, "title", "First Post", "created_at", "..." ),
// Map.of( "id", 2, "title", "Second Post", "created_at", "..." ),
// ]
// )
result := client.database.query({
"table": "users",
where: { "id": 1 },
include: {
"relation": "posts",
"type": "one-to-many",
"foreignKey": "user_id",
"primaryKey": "id",
select: ['id', 'title', 'created_at'],
where: { "published": true },
orderBy: { "column": "created_at", "order": "DESC" },
"limit": 10,
},
});
// Result:
// {
// "id": 1,
// "name": "John Doe",
// posts: [
// { "id": 1, "title": "First Post", "created_at": "..." },
// { "id": 2, "title": "Second Post", "created_at": "..." },
// ]
// }
var result = await ductape.database.query({
["table"] = "users",
where: { ["id"] = 1 },
include: {
["relation"] = "posts",
["type"] = "one-to-many",
["foreignKey"] = "user_id",
["primaryKey"] = "id",
select: ['id', 'title', 'created_at'],
where: { ["published"] = true },
orderBy: { ["column"] = "created_at", ["order"] = "DESC" },
["limit"] = 10,
},
});
// Result:
// {
// ["id"] = 1,
// ["name"] = "John Doe",
// posts: [
// { ["id"] = 1, ["title"] = "First Post", ["created_at"] = "..." },
// { ["id"] = 2, ["title"] = "Second Post", ["created_at"] = "..." },
// ]
// }
Many-to-Many Relationship
Fetch records through a junction table:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: { id: 1 },
include: {
relation: 'roles',
type: 'many-to-many',
through: 'user_roles',
throughForeignKey: 'user_id',
throughRelatedKey: 'role_id',
select: ['name', 'permissions'],
},
});
// Result:
// {
// id: 1,
// name: 'John Doe',
// roles: [
// { name: 'admin', permissions: ['read', 'write', 'delete'] },
// { name: 'editor', permissions: ['read', 'write'] },
// ]
// }
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of( "id", 1 ),
include: Map.of(
"relation", "roles",
"type", "many-to-many",
"through", "user_roles",
"throughForeignKey", "user_id",
"throughRelatedKey", "role_id",
select: ['name', 'permissions']
)
));
// Result:
// Map.of(
// "id", 1,
// "name", "John Doe",
// roles: [
// Map.of( "name", "admin", permissions: ['read', 'write', 'delete'] ),
// Map.of( "name", "editor", permissions: ['read', 'write'] ),
// ]
// )
result := client.database.query({
"table": "users",
where: { "id": 1 },
include: {
"relation": "roles",
"type": "many-to-many",
"through": "user_roles",
"throughForeignKey": "user_id",
"throughRelatedKey": "role_id",
select: ['name', 'permissions'],
},
});
// Result:
// {
// "id": 1,
// "name": "John Doe",
// roles: [
// { "name": "admin", permissions: ['read', 'write', 'delete'] },
// { "name": "editor", permissions: ['read', 'write'] },
// ]
// }
var result = await ductape.database.query({
["table"] = "users",
where: { ["id"] = 1 },
include: {
["relation"] = "roles",
["type"] = "many-to-many",
["through"] = "user_roles",
["throughForeignKey"] = "user_id",
["throughRelatedKey"] = "role_id",
select: ['name', 'permissions'],
},
});
// Result:
// {
// ["id"] = 1,
// ["name"] = "John Doe",
// roles: [
// { ["name"] = "admin", permissions: ['read', 'write', 'delete'] },
// { ["name"] = "editor", permissions: ['read', 'write'] },
// ]
// }
Multiple Includes
Include multiple relationships in one query:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: { id: 1 },
include: [
{
relation: 'profile',
type: 'many-to-one',
select: ['bio', 'avatar_url'],
},
{
relation: 'posts',
type: 'one-to-many',
foreignKey: 'author_id',
where: { published: true },
limit: 5,
},
{
relation: 'comments',
type: 'one-to-many',
foreignKey: 'user_id',
select: ['content', 'created_at'],
limit: 10,
},
],
});
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of( "id", 1 ),
include: [
Map.of(
"relation", "profile",
"type", "many-to-one",
select: ['bio', 'avatar_url']
),
Map.of(
"relation", "posts",
"type", "one-to-many",
"foreignKey", "author_id",
where: Map.of( "published", true ),
"limit", 5
),
Map.of(
"relation", "comments",
"type", "one-to-many",
"foreignKey", "user_id",
select: ['content', 'created_at'],
"limit", 10
),
]
));
result := client.database.query({
"table": "users",
where: { "id": 1 },
include: [
{
"relation": "profile",
"type": "many-to-one",
select: ['bio', 'avatar_url'],
},
{
"relation": "posts",
"type": "one-to-many",
"foreignKey": "author_id",
where: { "published": true },
"limit": 5,
},
{
"relation": "comments",
"type": "one-to-many",
"foreignKey": "user_id",
select: ['content', 'created_at'],
"limit": 10,
},
],
});
var result = await ductape.database.query({
["table"] = "users",
where: { ["id"] = 1 },
include: [
{
["relation"] = "profile",
["type"] = "many-to-one",
select: ['bio', 'avatar_url'],
},
{
["relation"] = "posts",
["type"] = "one-to-many",
["foreignKey"] = "author_id",
where: { ["published"] = true },
["limit"] = 5,
},
{
["relation"] = "comments",
["type"] = "one-to-many",
["foreignKey"] = "user_id",
select: ['content', 'created_at'],
["limit"] = 10,
},
],
});
Nested Includes
Load deeply nested relationships:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.query({
table: 'users',
where: { id: 1 },
include: {
relation: 'posts',
type: 'one-to-many',
select: ['id', 'title'],
include: {
relation: 'comments',
type: 'one-to-many',
foreignKey: 'post_id',
select: ['content', 'author_name'],
limit: 3,
},
},
});
// Result:
// {
// id: 1,
// name: 'John Doe',
// posts: [
// {
// id: 1,
// title: 'First Post',
// comments: [
// { content: 'Great post!', author_name: 'Jane' },
// { content: 'Thanks!', author_name: 'Bob' },
// ]
// }
// ]
// }
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of( "id", 1 ),
include: Map.of(
"relation", "posts",
"type", "one-to-many",
select: ['id', 'title'],
include: Map.of(
"relation", "comments",
"type", "one-to-many",
"foreignKey", "post_id",
select: ['content', 'author_name'],
"limit", 3
)
)
));
// Result:
// Map.of(
// "id", 1,
// "name", "John Doe",
// posts: [
// Map.of(
// "id", 1,
// "title", "First Post",
// comments: [
// Map.of( "content", "Great post!", "author_name", "Jane" ),
// Map.of( "content", "Thanks!", "author_name", "Bob" ),
// ]
// )
// ]
// )
result := client.database.query({
"table": "users",
where: { "id": 1 },
include: {
"relation": "posts",
"type": "one-to-many",
select: ['id', 'title'],
include: {
"relation": "comments",
"type": "one-to-many",
"foreignKey": "post_id",
select: ['content', 'author_name'],
"limit": 3,
},
},
});
// Result:
// {
// "id": 1,
// "name": "John Doe",
// posts: [
// {
// "id": 1,
// "title": "First Post",
// comments: [
// { "content": "Great post!", "author_name": "Jane" },
// { "content": "Thanks!", "author_name": "Bob" },
// ]
// }
// ]
// }
var result = await ductape.database.query({
["table"] = "users",
where: { ["id"] = 1 },
include: {
["relation"] = "posts",
["type"] = "one-to-many",
select: ['id', 'title'],
include: {
["relation"] = "comments",
["type"] = "one-to-many",
["foreignKey"] = "post_id",
select: ['content', 'author_name'],
["limit"] = 3,
},
},
});
// Result:
// {
// ["id"] = 1,
// ["name"] = "John Doe",
// posts: [
// {
// ["id"] = 1,
// ["title"] = "First Post",
// comments: [
// { ["content"] = "Great post!", ["author_name"] = "Jane" },
// { ["content"] = "Thanks!", ["author_name"] = "Bob" },
// ]
// }
// ]
// }
Raw Queries
For complex queries that can't be expressed with the query builder:
PostgreSQL
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.raw({
query: 'SELECT * FROM users WHERE created_at > $1 AND status = $2',
params: [new Date('2024-01-01'), 'active'],
});
console.log('Rows:', result.data);
console.log('Fields:', result.fields);
Map<String, Object> result = ductape.database.raw(Map.of(
"query", "SELECT * FROM users WHERE created_at > $1 AND status = $2",
params: [new Date('2024-01-01'), 'active']
));
System.out.println('"Rows", ", result.data);
System.out.println("Fields:', result.fields);
result := client.database.raw({
"query": "SELECT * FROM users WHERE created_at > $1 AND status = $2",
params: [new Date('2024-01-01'), 'active'],
});
fmt.Println('"Rows": ", result.data);
fmt.Println("Fields:', result.fields);
var result = await ductape.database.raw({
["query"] = "SELECT * FROM users WHERE created_at > $1 AND status = $2",
params: [new Date('2024-01-01'), 'active'],
});
Console.WriteLine('["Rows"] = ", result.data);
Console.WriteLine("Fields:', result.fields);
MySQL
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.raw({
query: 'SELECT * FROM users WHERE created_at > ? AND status = ?',
params: [new Date('2024-01-01'), 'active'],
});
Map<String, Object> result = ductape.database.raw(Map.of(
"query", "SELECT * FROM users WHERE created_at > ? AND status = ?",
params: [new Date('2024-01-01'), 'active']
));
result := client.database.raw({
"query": "SELECT * FROM users WHERE created_at > ? AND status = ?",
params: [new Date('2024-01-01'), 'active'],
});
var result = await ductape.database.raw({
["query"] = "SELECT * FROM users WHERE created_at > ? AND status = ?",
params: [new Date('2024-01-01'), 'active'],
});
MongoDB
- TypeScript
- Java
- Go
- .NET
const result = await ductape.database.raw({
query: {
status: 'active',
created_at: { $gte: new Date('2024-01-01') },
},
collection: 'users',
});
Map<String, Object> result = ductape.database.raw(Map.of(
query: Map.of(
"status", "active",
created_at: Map.of( $gte: new Date('2024-01-01') )
),
"collection", "users"
));
result := client.database.raw({
query: {
"status": "active",
created_at: { $gte: new Date('2024-01-01') },
},
"collection": "users",
});
var result = await ductape.database.raw({
query: {
["status"] = "active",
created_at: { $gte: new Date('2024-01-01') },
},
["collection"] = "users",
});
Query Result Structure
All query operations return a consistent result structure:
interface IQueryResult<T> {
data: T[]; // Array of matching records
count: number; // Total count (useful for pagination)
fields?: string[]; // Column names (for raw queries)
}
Query Options Reference
| Option | Type | Description |
|---|---|---|
table | string | Table or collection name |
select | string[] | Columns to return |
where | object | Filter conditions |
orderBy | object | object[] | Sort configuration |
limit | number | Maximum records to return |
offset | number | Records to skip |
include | object | object[] | Relationship includes |
env | string | Environment (if not connected) |
product | string | Product tag (if not connected) |
database | string | Database tag (if not connected) |
Examples by Use Case
Find One Record
- TypeScript
- Java
- Go
- .NET
const user = await ductape.database.query({
table: 'users',
where: { id: userId },
limit: 1,
});
const singleUser = user.data[0];
Map<String, Object> user = ductape.database.query(Map.of(
"table", "users",
where: Map.of( id: userId ),
"limit", 1
));
Map<String, Object> singleUser = user.data[0];
user := client.database.query({
"table": "users",
where: { id: userId },
"limit": 1,
});
singleUser := user.data[0];
var user = await ductape.database.query({
["table"] = "users",
where: { id: userId },
["limit"] = 1,
});
var singleUser = user.data[0];
Search with Pagination
- TypeScript
- Java
- Go
- .NET
async function searchUsers(query: string, page: number, pageSize: number) {
const result = await ductape.database.query({
table: 'users',
where: {
$or: [
{ name: { $like: `%${query}%` } },
{ email: { $like: `%${query}%` } },
],
},
orderBy: { column: 'name', order: 'ASC' },
limit: pageSize,
offset: (page - 1) * pageSize,
});
return {
users: result.data,
total: result.count,
page,
pageSize,
totalPages: Math.ceil(result.count / pageSize),
};
}
async function searchUsers(query: string, page: number, pageSize: number) Map.of(
Map<String, Object> result = ductape.database.query(Map.of(
"table", "users",
where: Map.of(
$or: [
Map.of( name: Map.of( $like: `%$Map.of(query)%` ) ),
Map.of( email: Map.of( $like: `%$Map.of(query)%` ) ),
]
),
orderBy: Map.of( "column", "name", "order", "ASC" ),
limit: pageSize,
offset: (page - 1) * pageSize
));
return Map.of(
users: result.data,
total: result.count,
page,
pageSize,
totalPages: Math.ceil(result.count / pageSize)
);
)
async function searchUsers(query: string, page: number, pageSize: number) {
result := client.database.query({
"table": "users",
where: {
$or: [
{ name: { $like: `%${query}%` } },
{ email: { $like: `%${query}%` } },
],
},
orderBy: { "column": "name", "order": "ASC" },
limit: pageSize,
offset: (page - 1) * pageSize,
});
return {
users: result.data,
total: result.count,
page,
pageSize,
totalPages: Math.ceil(result.count / pageSize),
};
}
async function searchUsers(query: string, page: number, pageSize: number) {
var result = await ductape.database.query({
["table"] = "users",
where: {
$or: [
{ name: { $like: `%${query}%` } },
{ email: { $like: `%${query}%` } },
],
},
orderBy: { ["column"] = "name", ["order"] = "ASC" },
limit: pageSize,
offset: (page - 1) * pageSize,
});
return {
users: result.data,
total: result.count,
page,
pageSize,
totalPages: Math.ceil(result.count / pageSize),
};
}
Recent Records
- TypeScript
- Java
- Go
- .NET
const recentOrders = await ductape.database.query({
table: 'orders',
where: {
created_at: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) },
},
orderBy: { column: 'created_at', order: 'DESC' },
limit: 50,
});
Map<String, Object> recentOrders = ductape.database.query(Map.of(
"table", "orders",
where: Map.of(
created_at: Map.of( $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) )
),
orderBy: Map.of( "column", "created_at", "order", "DESC" ),
"limit", 50
));
recentOrders := client.database.query({
"table": "orders",
where: {
created_at: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) },
},
orderBy: { "column": "created_at", "order": "DESC" },
"limit": 50,
});
var recentOrders = await ductape.database.query({
["table"] = "orders",
where: {
created_at: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) },
},
orderBy: { ["column"] = "created_at", ["order"] = "DESC" },
["limit"] = 50,
});
Filtered Dashboard Data
- TypeScript
- Java
- Go
- .NET
const dashboardData = await ductape.database.query({
table: 'orders',
select: ['id', 'customer_name', 'total', 'status', 'created_at'],
where: {
$and: [
{ status: { $in: ['pending', 'processing'] } },
{ total: { $gte: 100 } },
{ created_at: { $gte: new Date('2024-01-01') } },
],
},
orderBy: [
{ column: 'status', order: 'ASC' },
{ column: 'created_at', order: 'DESC' },
],
limit: 100,
});
Map<String, Object> dashboardData = ductape.database.query(Map.of(
"table", "orders",
select: ['id', 'customer_name', 'total', 'status', 'created_at'],
where: Map.of(
$and: [
Map.of( status: Map.of( $in: ['pending', 'processing'] ) ),
Map.of( total: Map.of( $"gte", 100 ) ),
Map.of( created_at: Map.of( $gte: new Date('2024-01-01') ) ),
]
),
orderBy: [
Map.of( "column", "status", "order", "ASC" ),
Map.of( "column", "created_at", "order", "DESC" ),
],
"limit", 100
));
dashboardData := client.database.query({
"table": "orders",
select: ['id', 'customer_name', 'total', 'status', 'created_at'],
where: {
$and: [
{ status: { $in: ['pending', 'processing'] } },
{ total: { $"gte": 100 } },
{ created_at: { $gte: new Date('2024-01-01') } },
],
},
orderBy: [
{ "column": "status", "order": "ASC" },
{ "column": "created_at", "order": "DESC" },
],
"limit": 100,
});
var dashboardData = await ductape.database.query({
["table"] = "orders",
select: ['id', 'customer_name', 'total', 'status', 'created_at'],
where: {
$and: [
{ status: { $in: ['pending', 'processing'] } },
{ total: { $["gte"] = 100 } },
{ created_at: { $gte: new Date('2024-01-01') } },
],
},
orderBy: [
{ ["column"] = "status", ["order"] = "ASC" },
{ ["column"] = "created_at", ["order"] = "DESC" },
],
["limit"] = 100,
});
Next Steps
- Writing Data - Insert, update, and delete records
- Aggregations - Count, sum, and group data
- Transactions - Execute queries atomically
- Direct Queries - Advanced query patterns