Skip to content

查询语法

BucketDB 提供 8 种查询操作符,支持灵活的文档查询。

基础查询

等值查询

最简单的查询方式,直接指定字段值:

typescript
// 查找所有 status 为 'active' 的用户
const users = await collection.find({ status: 'active' });

// 多字段等值查询(AND 逻辑)
const users = await collection.find({
  status: 'active',
  role: 'admin'
});

等价于:

typescript
const users = await collection.find({
  status: { $eq: 'active' },
  role: { $eq: 'admin' }
});

比较操作符

$eq - 等于

typescript
const users = await collection.find({ age: { $eq: 25 } });

$ne - 不等于

typescript
// 查找所有非删除状态的用户
const users = await collection.find({ status: { $ne: 'deleted' } });

$gt - 大于

typescript
// 查找年龄大于 18 的用户
const users = await collection.find({ age: { $gt: 18 } });

$gte - 大于等于

typescript
// 查找年龄 >= 18 的用户
const users = await collection.find({ age: { $gte: 18 } });

$lt - 小于

typescript
// 查找年龄小于 65 的用户
const users = await collection.find({ age: { $lt: 65 } });

$lte - 小于等于

typescript
// 查找年龄 <= 65 的用户
const users = await collection.find({ age: { $lte: 65 } });

数组操作符

$in - 在数组中

typescript
// 查找状态为 active 或 pending 的用户
const users = await collection.find({
  status: { $in: ['active', 'pending'] }
});

$nin - 不在数组中

typescript
// 查找状态不是 deleted 或 banned 的用户
const users = await collection.find({
  status: { $nin: ['deleted', 'banned'] }
});

组合查询

多个操作符(AND 逻辑)

同一字段可以使用多个操作符:

typescript
// 查找年龄在 18-65 之间的用户
const users = await collection.find({
  age: { $gte: 18, $lt: 65 }
});

多个字段(AND 逻辑)

不同字段的条件会自动组合:

typescript
// 查找活跃的成年用户
const users = await collection.find({
  status: 'active',
  age: { $gte: 18 }
});

// 复杂组合
const users = await collection.find({
  status: { $in: ['active', 'pending'] },
  age: { $gte: 18, $lt: 65 },
  role: { $ne: 'guest' }
});

分页查询

使用 limitoffset 实现分页:

typescript
// 第一页:前 10 条
const page1 = await collection.find({}, { limit: 10, offset: 0 });

// 第二页:第 11-20 条
const page2 = await collection.find({}, { limit: 10, offset: 10 });

// 第三页:第 21-30 条
const page3 = await collection.find({}, { limit: 10, offset: 20 });

分页辅助函数

typescript
async function getPage(
  filter: QueryFilter<User>,
  page: number,
  pageSize: number = 10
) {
  return await collection.find(filter, {
    limit: pageSize,
    offset: (page - 1) * pageSize
  });
}

// 使用
const page1 = await getPage({ status: 'active' }, 1, 20);
const page2 = await getPage({ status: 'active' }, 2, 20);

迭代器模式

typescript
async function* paginateAll(
  filter: QueryFilter<User>,
  pageSize: number = 100
) {
  let offset = 0;

  while (true) {
    const page = await collection.find(filter, { limit: pageSize, offset });
    if (page.length === 0) break;

    yield page;
    offset += page.length;

    if (page.length < pageSize) break;  // 最后一页
  }
}

// 使用
for await (const page of paginateAll({ status: 'active' })) {
  console.log(`Processing ${page.length} users`);
  // 处理当前页
}

查询最佳实践

1. 使用具体的过滤条件

typescript
// ✅ 好:具体的条件,减少扫描
const users = await collection.find({
  status: 'active',
  age: { $gte: 18 }
});

// ❌ 差:空过滤,扫描所有文档
const all = await collection.find({});

2. 选择性字段优先

优先使用选择性高的字段(值分布均匀的字段):

typescript
// ✅ 好:email 唯一性高
const user = await collection.find({ email: 'alice@example.com' });

// ⚠️ 差:status 值有限,选择性低
const users = await collection.find({ status: 'active' });

3. 合理使用分页

大结果集必须使用分页:

typescript
// ✅ 好:分页获取
const page = await collection.find({}, { limit: 100, offset: 0 });

// ❌ 差:一次获取所有(可能数万条)
const all = await collection.find({});

4. 避免过度过滤

不必要的条件会降低性能:

typescript
// ✅ 好:只用必要条件
const users = await collection.find({ id: 'user-123' });

// ❌ 差:id 已经唯一,其他条件多余
const users = await collection.find({
  id: 'user-123',
  status: 'active',  // 多余
  age: { $gte: 0 }   // 多余
});

性能提示

  • 分片数量 - 根据文档数量选择合适的分片数(见核心概念
  • 批量查询 - 尽量减少查询次数,合理使用 limit
  • 字段选择性 - 优先使用选择性高的字段查询
  • 缓存结果 - 对频繁查询的结果进行应用层缓存

类型安全

TypeScript 会自动推断查询类型:

typescript
interface User extends Document {
  name: string;
  age: number;
  status: 'active' | 'inactive';
}

const users = db.collection<User>('users');

// ✅ 类型安全:字段和值都会被检查
await users.find({ status: 'active' });

// ❌ 编译错误:字段不存在
await users.find({ foo: 'bar' });

// ❌ 编译错误:值类型不匹配
await users.find({ status: 'invalid' });

// ✅ 类型推断:操作符值类型正确
await users.find({ age: { $gte: 18 } });

// ❌ 编译错误:操作符值类型错误
await users.find({ age: { $gte: 'eighteen' } });

下一步

Released under the MIT License.