# @dudousxd/nestjs-filter-drizzle 中文文档

规范地址：https://npmcn.com/package/%40dudousxd/nestjs-filter-drizzle/

版本：0\.3\.0
npm 元数据更新时间：2026-11-12T05:46:39.284Z
中文译文更新时间：2026-11-14T08:33:32.133Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40dudousxd/nestjs-filter-drizzle
原文对照：https://npmcn.com/package/%40dudousxd/nestjs-filter-drizzle/?lang=original
项目主页：https://davidecarvalho.github.io/aviary/docs/filter
源码仓库：https://github.com/DavideCarvalho/nestjs-filter

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：207 kB，37 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=24
- 运行依赖：0 个
- peer 依赖：drizzle-orm \>=0\.40\.0 \<1\.0\.0，@nestjs/core \>=10\.0\.0，@nestjs/common \>=10\.0\.0，@nestjs/drizzle \>=0\.0\.2 \<1\.0\.0，reflect-metadata \>=0\.1\.13，@dudousxd/nestjs-filter ^2\.0\.1
- 首次发布：2026-09-29T08:20:34.223Z
- 最新版本发布：2026-11-12T05:46:38.822Z
- 近 30 天下载量：2101（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：8（近 12 个月 8 个）

## 中文简介

@dudousxd/nestjs-filter的 Drizzle ORM适配器.

## 安装

```sh
npm install @dudousxd/nestjs-filter-drizzle
```

也可以使用：`pnpm add @dudousxd/nestjs-filter-drizzle`、`yarn add @dudousxd/nestjs-filter-drizzle`、`bun add @dudousxd/nestjs-filter-drizzle`

## README

# @dudousxd/nestjs-filter-dryzzle (英语)

Drizzle ORM 适应器 [`@dudousxd/nestjs-filter`](https://npmcn.com/package/README.md)。 。 。 .

提供 `DrizzleFilter`, (中文(简体) ), `DrizzleAdapter`, (中文(简体) ), `DrizzleQuery`,以及 `DrizzleFilterModule`。 。 。 . Postgres,MySQL和SQLite得到支持(每个方言都运行着交叉适应器合同套件).

## 安装

```bash
pnpm add @dudousxd/nestjs-filter @dudousxd/nestjs-filter-drizzle
```

同伴依赖性 : `drizzle-orm` 0.40 < 1.0, (中文(简体) ), `@nestjs/common` >=10, `@nestjs/core` 十点. 可选 : [`@nestjs/drizzle`](https://docs.nestjs.com/data/drizzle) ^ 0.0.2 < 1.0,适配器默认使用其数据库.

## 快速启动

```typescript
// schema.ts — the table object IS the entity
import { relations } from 'drizzle-orm';
import { integer, pgTable, serial, text } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  age: integer('age').notNull(),
  role: text('role').notNull(),
});

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: text('title').notNull(),
  status: text('status').notNull(),
  authorId: integer('author_id').notNull(),
});

// relations() powers includes, dot-notation filters, whereHas(), aggregates and describe()
export const usersRelations = relations(users, ({ many }) => ({ posts: many(posts) }));
export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, { fields: [posts.authorId], references: [users.id] }),
}));

export const schema = { users, posts, usersRelations, postsRelations };
```

```typescript
// user.filter.ts
import { Injectable } from '@nestjs/common';
import { Filterable, FilterFor } from '@dudousxd/nestjs-filter';
import { DrizzleFilter } from '@dudousxd/nestjs-filter-drizzle';
import { eq, gte } from 'drizzle-orm';
import { posts, users } from './schema.js';

@Injectable()
@Filterable({ entity: users })
export class UserFilter extends DrizzleFilter<typeof users> {
  static readonly sort = ['name', 'age', 'posts.$count'];
  static readonly search = ['name'];
  static readonly includes = ['posts'];

  @FilterFor('minAge')
  applyMinAge(value: number) {
    this.$query.where(gte(users.age, value));
  }

  @FilterFor('name')
  applyName(value: string) {
    this.whereILike('name', value); // escaped; ILIKE on Postgres, lower() LIKE elsewhere
  }

  @FilterFor('hasPublished')
  applyHasPublished(value: boolean) {
    if (value) this.$query.whereHas('posts', (p) => eq((p as typeof posts).status, 'published'));
  }
}
```

```typescript
// app.module.ts — the database comes from NestJS's @nestjs/drizzle (https://docs.nestjs.com/data/drizzle)
import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { FilterModule } from '@dudousxd/nestjs-filter';
import { drizzleAdapter } from '@dudousxd/nestjs-filter-drizzle';
import { drizzle } from 'drizzle-orm/node-postgres';
import { schema } from './schema.js';

@Module({
  imports: [
    DrizzleModule.forRoot({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    // no `connection`/`db`: injects getDrizzleToken(name) from @nestjs/drizzle
    FilterModule.forRoot({ inputNormalizer: 'camelCase', adapter: drizzleAdapter() }),
    FilterModule.forFeature([UserFilter]),
  ],
  controllers: [UsersController],
})
export class AppModule {}
```

已命名的连接 : `drizzleAdapter({ name: 'reports' })` 页:1 `DrizzleModule.forRoot({ name: 'reports', ... })`。 。 。 . `@nestjs/drizzle` 是一个可选的对等点:没有它,就通过自己的标志(`drizzleAdapter({ connection: DRIZZLE })`, (中文(简体) ), 提供来源a `@Global()` 模块)或实例(`drizzleAdapter({ db })`) (中文(简体) ).

```typescript
// users.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ApplyFilter } from '@dudousxd/nestjs-filter';
import type { DrizzleQuery } from '@dudousxd/nestjs-filter-drizzle';

@Controller('users')
export class UsersController {
  @Get()
  list(@ApplyFilter(UserFilter) q: DrizzleQuery<typeof users>) {
    return q.execute(); // or q.executeAndCount(), q.count(), q.toSelect(), q.toSQL()
  }
}
```

`GET /users?minAge=18&name=al&sort=-age&include=posts&paginate[page]=0&paginate[size]=20`

## 它如何映射到 Drizzle 上

| 概念 | MikroORM / TypeORM 适配器 | 滴滴适配器 |
| --- | --- | --- |
| 实体 | 装饰类(`User`(中文(简体) ) | 表格对象 (`users`(中文(简体) ) |
| 元数据 | ORM 元数据登记册 | `getTableColumns(table)` +该 `relations()` 在你的计划 |
| `this.$query` | oRM 的查询构建器 | `DrizzleQuery` - 累积器 `SQL` 条件、顺序、窗口、投影和包括,作为 " 一体行动 " 实现 `db.select().from(table)` 执行时 |
| 关系过滤器( E)`posts.status`, (中文(简体) ), `@Relations`, (中文(简体) ), `related()`(中文(简体) ) | 联 合 | 关联 `EXISTS (…)` 子点 |
| 排序/ 区分于一个路径( O) (`manager.name`(中文(简体) ) | 联 合 | 相關相關相關相關相關相關相關相關分母 |
| `include` | 加入/ ORM 填充 | 批次 `SELECT … WHERE fk IN (…)` 按关系分列 `row.posts[]` 编号 : `row.author` (形状) `db.query…findMany({ with })` 返回) |
| `findAndCount` 共计 | ORM 计数 | `count(*)` 平起平起平起地 `distinct`(中文(简体) ) |
| 合计数(`posts.$count`(中文(简体) ) | 关联子点 | 关联子点 |

根查询从不加入, 因此它总是每个匹配的父返回一行 : `LIMIT`编号 :`OFFSET` 财务报告和审定财务报表 `COUNT(*)` 不管请求涉及什么关系 都要保持精确.

### `DrizzleQuery` API 密码

| 成员 |  |
| --- | --- |
| `where(...conds)` | 和SQL条件`undefined` 被忽略 —— 作曲 `and()`编号 :`or()` 自由参加) |
| `andWhere(cond | { col: value })` | 也接受平等地图(阵列) – `IN`, (中文(简体) ), `null` → `IS NULL`(中文(简体) ) |
| `whereHas(path, (target) => cond?)` 编号 : `whereDoesntHave(...)` | 关联 `EXISTS` 超过关系路径( e)`'posts.comments'`(中文(简体) ) |
| `orderBy(...terms)`, (中文(简体) ), `clearOrderBy()`, (中文(简体) ), `limit(n)`, (中文(简体) ), `offset(n)` | 顺序和窗口 |
| `select(fields)`, (中文(简体) ), `addSelect(fields)`, (中文(简体) ), `distinct()` | 预测 |
| `include(...paths)` | 已装入的关系 `execute()` |
| `columns`, (中文(简体) ), `table`, (中文(简体) ), `db`, (中文(简体) ), `dialect` | 表格的列(可能别名)和执行上下文 |
| `execute()`, (中文(简体) ), `count()`, (中文(简体) ), `executeAndCount()` | 运行它 |
| `toSelect()`, (中文(简体) ), `toSQL()` | 已成形的细管构建器 / SQL + 参数 |

### 双倍关系过滤器

当过滤器通过时 `@Relations` (或 `this.related(...)`页:1 `$query` 目标a **别名** 内部的表格 `EXISTS` 亚克瑞. 读取列通过 `this.columns` (或 `whereHas`而不是此类过滤器中导入的表格对象:

```typescript
@FilterFor('postStatus')
applyStatus(value: string) {
  this.$query.where(eq(this.columns.status, value));
}
```

## 已计算字段

与其他适配器相同的三个源形式. 因为适配器从来没有加入,一个 字符串源中的不合格列总是表示根表的列; 一个函数 来源收到 `{ alias: <table name>, em: db }` 并可能返回 SQL 字符串、 细雨 `sql` 片段,或选择的构建器(用作平板子:

```typescript
@Filterable({
  entity: users,
  computed: {
    doubleAge: '(age * 2)',
    label: { source: `name || ' <' || role || '>'`, project: true },
  },
})
export class UserFilter extends DrizzleFilter<typeof users> {
  @Computed({ type: 'number' })
  postCount() {
    return sql`(select count(*) from ${posts} where ${posts.authorId} = ${users.id})`;
  }
}
```

## 测试

不需要数据库:对照一个过滤器运行 `DrizzleQuery` 结束 `drizzle.mock()` 并申明SQL.

```typescript
import { drizzle } from 'drizzle-orm/node-postgres';

const q = new DrizzleAdapter(drizzle.mock()).query(users);
await runner.apply(UserFilter, { name: 'al', minAge: 18 }, q);
expect(q.toSQL()).toEqual({
  sql: 'select "id", "name", "age" from "users" where ("users"."name" ilike $1 and "users"."age" >= $2)',
  params: ['%al%', 18],
});
```

`FilterTestingModule` + 键 `makeMockQueryBuilder` 也工作:模拟记录 `['where', SQL]` 调用,您可以用方言调用`new PgDialect().sqlToQuery(sql)`) (中文(简体) ).

## 限制

-   **仅细流 0.x** (单位:千美元)`relations()` (原始内容存档于2017-10-01). Drizzle 1.0's `defineRelations` 尚未读取.
-   **无多对多** 关系类型: 细雨模型化为相交表, 因此显示 作为一对一的接合点(`user.userTags[].tag`) (中文(简体) ).
-   **JSON 子路径** (单位:千美元)`metadata.tier`)不能解决(MikroORM适配器支持它们).
-   **复合-关键关系** 被跳过 `include`;过滤通过它们有效.
-   **矢量搜索** (单位:千美元)`search = { vector }`)是只使用 Postgres .
-   **代码** (单位:千美元)`@dudousxd/nestjs-filter-codegen`通过TypeScript AST读取实体类; 它还没有得到 `filterFields` 从Drizzle桌子.

## API 参考

### `DrizzleFilter<TTable>`

抽象基础类. `this.$query` 是一个 `DrizzleQuery<TTable>`。帮助者: `columns`, (中文(简体) ), `whereLike`, (中文(简体) ), `whereILike`, (中文(简体) ), `whereBeginsWith`, (中文(简体) ), `whereEndsWith` (都逃脱了价值).

### `DrizzleFilterModule.forRoot({ connection | db, schema?, dialect?, imports? })`

登记册 `DrizzleAdapter` 作为过滤器适配器. `connection` 您的注射符号 细雨实例(由全球提供,或由以下所列模块提供) `imports`(三); `db` 通过 直接出现. `schema` 默认为该实例的设定. `drizzleAdapter(options)` 和描述词一样 `FilterModule.forRoot({ adapter })`。 。 。 .

### `DrizzleAdapter`

执行 `FilterAdapter`。 。 。 . `adapter.query(table)` 创建一个 `DrizzleQuery` 服务:

```typescript
const q = adapter.query(users);
await runner.apply(UserFilter, input, q);
const { rows, total } = await q.executeAndCount();
```

## 常见问题

### @dudousxd/nestjs-filter-drizzle 是什么？

@dudousxd/nestjs-filter的 Drizzle ORM适配器\.

### 如何安装 @dudousxd/nestjs-filter-drizzle？

在项目目录运行 npm install @dudousxd/nestjs-filter-drizzle，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：drizzle-orm（\>=0\.40\.0 \<1\.0\.0）、@nestjs/core（\>=10\.0\.0）、@nestjs/common（\>=10\.0\.0）、reflect-metadata（\>=0\.1\.13）、@dudousxd/nestjs-filter（^2\.0\.1）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @dudousxd/nestjs-filter-drizzle 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @dudousxd/nestjs-filter-drizzle 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @dudousxd/nestjs-filter-drizzle 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=24。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @dudousxd/nestjs-filter-drizzle 可以商用吗？

@dudousxd/nestjs-filter-drizzle 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @dudousxd/nestjs-filter-drizzle 的下载量有多少？

根据 npm 官方下载统计，@dudousxd/nestjs-filter-drizzle 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,101 次，日均约 70 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @dudousxd/nestjs-filter-drizzle 还在维护吗？

最新版本 0\.3\.0 发布于 2026/11/12（2 天前）；至今共发布 8 个版本，其中过去 12 个月发布了 8 个；首次发布于 2026/09/29。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

