# @cerbos/orm-mongoose 中文文档

规范地址：https://npmcn.com/package/%40cerbos/orm-mongoose/

版本：3\.0\.0
npm 元数据更新时间：2026-08-03T16:04:38.362Z
中文译文更新时间：2026-11-09T08:53:42.615Z
软件包许可：Apache-2\.0

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

原始 npm 页面：https://www.npmjs.com/package/%40cerbos/orm-mongoose
原文对照：https://npmcn.com/package/%40cerbos/orm-mongoose/?lang=original
项目主页：https://cerbos.dev/
源码仓库：https://github.com/cerbos/query-plan-adapters

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

- 包体积（解压后）：267 kB，9 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.0\.0
- 运行依赖：2 个
- 首次发布：2023-06-27T21:02:00.811Z
- 最新版本发布：2026-08-03T16:04:38.051Z
- 近 30 天下载量：3266（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：9（近 12 个月 3 个）

## 中文简介

一个适配器库 [赛博斯](https://cerbos.dev/) 查询计划( E)[计划资源 API](https://docs.cerbos.dev/cerbos/latest/api/index.html#resources-query-plan))反应并将其转换为 [乌鸦](https://mongoosejs.com/) 过滤器。 这是脱口秀

## 安装

```sh
npm install @cerbos/orm-mongoose
```

也可以使用：`pnpm add @cerbos/orm-mongoose`、`yarn add @cerbos/orm-mongoose`、`bun add @cerbos/orm-mongoose`

## README

# Cerbos + Mongoose ORM 适应器

一个适配器库 [赛博斯](https://cerbos.dev/) 查询计划( E)[计划资源 API](https://docs.cerbos.dev/cerbos/latest/api/index.html#resources-query-plan))反应并将其转换为 [乌鸦](https://mongoosejs.com/) 过滤器。 它旨在与一个已经使用该软件的项目同时运行 [Cerbos Java 脚本 SDK](https://github.com/cerbos/cerbos-sdk-javascript) 以获取查询计划,从而将授权逻辑推倒到 MongoDB .

## 如何运作

1.  使用 Cerbos 客户端(`@cerbos/http` 或者说 `@cerbos/grpc`打电话 `planResources` 并获得 `PlanResourcesResponse`。 。 。 .
2.  提供 `queryPlanToMongoose` 以及一个可选的映射器 来描述 Cerbos 属性路径与您的文档计划的关系.
3.  适配器走 Cerbos 表达式树,将支持的运算符翻译为 MongoDB 语法,然后返回 `{ kind, filters? }`。 。 。 .
4.  检查 `result.kind`数字 :
    -   `ALWAYS_ALLOWED`:呼叫者可以查询,无需额外的过滤.
    -   `ALWAYS_DENIED`:短路并返回空结果集.
    -   `CONDITIONAL`: 用 `result.filters`。 。 。 .

您可以将适配器输出与现有的应用程序过滤器合并(例如,通过 `$and`)在发布Mongoose查询之前.

## 支持的运算符

| 类别 | 运算符 | 行为 |
| --- | --- | --- |
| 逻辑 | `and`, (中文(简体) ), `or`, (中文(简体) ), `not` | 构建 `$and`, (中文(简体) ), `$or`,以及 `$nor` 组合. |
| 比较 | `eq`, (中文(简体) ), `ne`, (中文(简体) ), `lt`, (中文(简体) ), `le`, (中文(简体) ), `gt`, (中文(简体) ), `ge` | 输出 `$eq`, (中文(简体) ), `$ne`, (中文(简体) ), `$lt`, (中文(简体) ), `$lte`, (中文(简体) ), `$gt`, (中文(简体) ), `$gte` 检查与绘图的字段. |
| 成员 | `in`, (中文(简体) ), `hasIntersection` | `$in` 在简单的列表中,或 `$elemMatch` 瞄准数组关系时; `hasIntersection` 支持一个直接阵列字段或一个 `map` 计划内投影. |
| 字符串助手 | `contains`, (中文(简体) ), `startsWith`, (中文(简体) ), `endsWith` | 生成从正则表达式中逃出,这些表达式的目标为子字符串,前缀,或后缀. |
| 存在助手 | `isSet`, (中文(简体) ), `exists` | 用途 `$exists`编号 :`$ne: null` 用于平板和 `$elemMatch` 用于收藏. |
| 收藏助手 | `filter`, (中文(简体) ), `lambda`, (中文(简体) ), `map`, (中文(简体) ), `all` | 将 Cerbos 收藏表达式翻译为范围化 `$elemMatch` 过滤器和羊肉达变量映射到正确的嵌入路径. `all` 需要存储字段为数组. |
| 算术和价值 | `add`, (中文(简体) ), `sub`, (中文(简体) ), `mult`, (中文(简体) ), `div`, (中文(简体) ), `mod`, (中文(简体) ), `if`, (中文(简体) ), `size`, (中文(简体) ), `index`, (中文(简体) ), `get-field` | 使用文档级别 MongoDB `$expr` 表达. division需要非零常分母;索引需要非负整数常数并添加每文档边框检查. |
| 转换和匹配 | `string`, (中文(简体) ), `double`, (中文(简体) ), `int`, (中文(简体) ), `timestamp`, (中文(简体) ), `matches` | 使用被守护的MongoDB转换和正则表达式. Timerstamps在CEL即时范围内接受BSON日期或毫秒精确的RFC 3339字符串. Regex匹配接受一个经验证的通用的RE2/PCRE2子集. |
| 等级 | `hierarchy`, (中文(简体) ), `ancestorOf`, (中文(简体) ), `descendentOf`, (中文(简体) ), `overlaps` | 使用字面前缀和祖先列表过滤器来翻译一个已绘制的scalar分级路径. |

未列入上述原因的操作人员 `queryPlanToMongoose` 要掷出 `Unsupported operator: <name>`。 。 。 .

`exists_one` 响亮失败, 因为普通匹配过滤器无法为已失效元素保存精确匹配的红外线和 CEL 错误语义 .

当存储的 BSON 类型在 CEL 兼容源类型之外或解析失败时,转换失败关闭. `double` 财务报告和审定财务报表 `int` 接受字符串和数字 BSON 值,但不使用布尔; `int` 还拒绝BSON日期,而不是将其解释为毫秒. `string` 接受字符串、布尔值和数值。 失败的转换仍然被拒绝.

时间戳值必须在协调世界时的即时范围内下降(`0001-01-01T00:00:00Z` 结束 `9999-12-31T23:59:59.999Z`) (中文(简体) ). 字符串必须使用不超过三个分数-秒数的RFC 3339语法,与BSON Date的毫秒精度相匹配. 高精度或外程的字符串和 BSON 日期失败而关闭,而不是被默默地切入到不同的CEL瞬间.

`matches` 支持字节, `.`,则 `*`, (中文(简体) ), `+`,以及 `?` 参数,领先 `^`终端 `$`,并逃脱了regex元特征。 其他的构造失败关闭 。 一个终端 `$` 被翻译为 PCRE2 的绝对文本端主播,因此MongoDB在最终新线之前无法匹配,保留了 RE2 语义.

## 履约合同

适配器对 Cerbos PDP 0.54.0 `checkResource` 使用20个敌对种子文件和真正的MongoDB 7和8个查询。 Spring Data适配器为这个相容快照定义了参考语义.

| 分类 | 覆盖范围 |
| --- | --- |
| 甲骨文测试 | 85 参考符合性动作外加regex,订购索引/`get-field`,和时间戳探测器(88个动作) |
| 未关闭 | 29项参考行动 |
| 已知的规划者差异 | `has()` cerbos计划员将缺失的属性折叠到 `ALWAYS_ALLOWED`时 `checkResource` 否认缺少属性文件 。 在计划员修好之前,请使用 `R.attr.x != null` 用于数据库支持的属性,而不是 `has(R.attr.x)` |

失败的闭合套件包括内部精确的一要素、汇总表达式或外文件参考 `$elemMatch`,嵌入式收集计数,相关可变可变成员,不安全的分数/非无限算法,并否定了无法保存CEL三值误差语义的无效收集上游. 这些计划不是无声地贬低MongoDB过滤器.

## 所需资源

-   Cerbos > v0.16 + 两者之一 `@cerbos/http` 或者说 `@cerbos/grpc` 客户端

## 系统要求

-   节点.js 22.0.0
-   Mong 9.x
-   MongoDB 7.0 或更新

## 安装

```bash
npm install @cerbos/orm-mongoose
```

## API 密码

```ts
import {
  queryPlanToMongoose,
  PlanKind,
  type Mapper,
} from "@cerbos/orm-mongoose";

const result = queryPlanToMongoose({
  queryPlan, // PlanResourcesResponse from Cerbos
  mapper, // optional Mapper - see below
});

if (result.kind === PlanKind.CONDITIONAL) {
  await MyModel.find(result.filters);
}
```

`PlanKind` 从 `@cerbos/core`数字 :

```ts
export enum PlanKind {
  ALWAYS_ALLOWED = "KIND_ALWAYS_ALLOWED",
  ALWAYS_DENIED = "KIND_ALWAYS_DENIED",
  CONDITIONAL = "KIND_CONDITIONAL",
}
```

### 映射器配置

Cerbos 查询计划引用字段, 使用路径如 `request.resource.attr.title`。使用映射器将这些名称翻译为您 Mongoose 模型中的路径,并描述关系/收集,以便适配器生成 `$elemMatch` 需要时过滤器.

```ts
export type MapperConfig = {
  field?: string;
  nullable?: boolean;
  valueParser?: (value: any) => any;
  relation?: {
    name: string;
    type: "one" | "many";
    field?: string;
    fields?: Record<string, MapperConfig>;
  };
};

export type Mapper =
  | Record<string, MapperConfig>
  | ((key: string) => MapperConfig);
```

-   `field` 将单一 Cerbos 路径重写到 MongoDB 中不同的字段 .
-   `nullable` 声明存储 `null` 代表缺少 Cerbos 属性。 比较会添加一个非null守护符,因此MongoDB不会将CEL评价错误变成授权匹配. 不要设置为字段 `null` 是一个明确的 Cerbos 值.
-   `valueParser` 在过滤器构建过程中会转换叶子值。 当 Cerbos 计划中包含需要转换为 MongoDB 特定类型的字符串表达式时(例如将字符串转换为 `ObjectId`) (中文(简体) ). 解析器应用到每个值 `eq`, (中文(简体) ), `ne`, (中文(简体) ), `lt`, (中文(简体) ), `le`, (中文(简体) ), `gt`, (中文(简体) ), `ge`,以及 `in` 操作员。 也通过 `fields` 地图.
-   `relation` 描述嵌入式文档(`type: "one"`)或数组(`type: "many"`) (中文(简体) ). 何时 `field` 用于比较(例如匹配) `createdBy.id` 无 `$elemMatch`) (中文(简体) ).
-   `fields` 补给层覆盖,所以 lambda 表达式,例如 `tag.name` 可以被映射到正确的属性.

如果您省略了映射器, 适配器会逐字使用查询计划路径, 只有当您的 Mongo 文档遵循 Cerbos 命名惯例时才有效 .

#### 直接字段

```ts
const mapper: Mapper = {
  "request.resource.attr.aBool": { field: "aBool" },
  "request.resource.attr.aString": { field: "title" },
  "request.principal.attr.department": { field: "principalDepartment" },
};
```

#### 关系和收藏

使用 `relation` 当绘制嵌入对象或阵列时. `type: "one"` 映射到嵌入/单一关系和结果的点化字段路径,同时 `type: "many"` 映射到数组并让适配器放出 `$elemMatch` 条件。 可选 `fields` 映射让您重命名 lambda 表达式中引用的嵌入属性 .

```ts
const mapper: Mapper = {
  "request.resource.attr.createdBy": {
    relation: {
      name: "createdBy",
      type: "one",
      field: "id",
    },
  },
  "request.resource.attr.tags": {
    relation: {
      name: "tags",
      type: "many",
      fields: {
        id: { field: "id" },
        name: { field: "name" },
      },
    },
  },
};
```

#### 实际收集操作员

了解收集的操作员(`filter`, (中文(简体) ), `exists`, (中文(简体) ), `hasIntersection`, (中文(简体) ), `map`,以及 `all`)要求映射器声明与 `type: "many"`。适配器自动瞄准羊肉达变量并使用 `fields` 翻译表达式时的映射 `tag.name`数字 :

```ts
const mapper: Mapper = {
  "request.resource.attr.tags": {
    relation: {
      name: "tags",
      type: "many",
      fields: {
        name: { field: "name", nullable: true },
      },
    },
  },
};
```

-   `exists` 财务报告和审定财务报表 `filter` 将翻译条件包入 `$elemMatch`。 。 。 .
-   `hasIntersection` 既适用于平面阵列,也适用于对象阵列;当计划使用时 `map(lambda(tag.name))` 适配器项目 `tag.name` 改为 `tags.$elemMatch.name`。 。 。 .
-   `all` 将 lambda 条件转换为否定条件 `$elemMatch` 因此,所有要素必须满足上游.
-   一个赤裸的 `map` 表达式验证每个元素中引用的嵌入路径.

#### 映射函数

如果您的映射遵循了可预测的模式, 您也可以提供函数 :

```ts
const mapper: Mapper = (path) => {
  if (path.startsWith("request.resource.attr.")) {
    return { field: path.replace("request.resource.attr.", "") };
  }
  if (path.startsWith("request.principal.attr.")) {
    return { field: `principal.${path.replace("request.principal.attr.", "")}` };
  }
  return { field: path };
};
```

#### 数值解析

使用 `valueParser` 将 Cerbos 计划中的值转换成 MongoDB 所期望的类型。 一个常用的大小写是将字符串ID转换为 `ObjectId`数字 :

```ts
import { Types } from "mongoose";

const mapper: Mapper = {
  "request.resource.attr.id": {
    field: "_id",
    valueParser: (value) => new Types.ObjectId(value),
  },
};
```

`valueParser` 并且通过 `fields` 地图 :

```ts
const mapper: Mapper = {
  "request.resource.attr.createdBy": {
    relation: {
      name: "createdBy",
      type: "one",
      field: "id",
      fields: {
        id: {
          field: "id",
          valueParser: (value) => new Types.ObjectId(value),
        },
      },
    },
  },
};
```

## 用法实例

```ts
import { GRPC as Cerbos } from "@cerbos/grpc";
import mongoose from "mongoose";
import {
  queryPlanToMongoose,
  PlanKind,
  type Mapper,
} from "@cerbos/orm-mongoose";

await mongoose.connect("mongodb://127.0.0.1:27017/test");
const cerbos = new Cerbos("localhost:3592", { tls: false });
const MyModel = mongoose.model("MyModel", /* ... schema ... */);

const mapper: Mapper = {
  "request.resource.attr.title": { field: "title" },
  "request.resource.attr.owner": {
    relation: { name: "owner", type: "one", field: "id" },
  },
  "request.resource.attr.tags": {
    relation: {
      name: "tags",
      type: "many",
      fields: { name: { field: "name" } },
    },
  },
};

const queryPlan = await cerbos.planResources({
  principal: { id: "user1", roles: ["USER"] },
  resource: { kind: "document" },
  action: "view",
});

const result = queryPlanToMongoose({ queryPlan, mapper });

if (result.kind === PlanKind.ALWAYS_DENIED) {
  return [];
}

const filters = result.kind === PlanKind.CONDITIONAL ? result.filters : {};
const records = await MyModel.find(filters);
```

如果您已经拥有应用程序特定标准,您可以使用 `$and`数字 :

```ts
const filters = result.kind === PlanKind.CONDITIONAL ? result.filters : {};
await MyModel.find({ $and: [filters ?? {}, { archived: false }] });
```

## 处理错误

`queryPlanToMongoose` 在以下情景中抛出描述性错误 :

-   计划不是Cerbos的 `PlanKind` 数值(`Invalid query plan.`) (中文(简体) ).
-   有条件的计划省略 `operator`编号 :`operands` 结构`Invalid Cerbos expression structure`) (中文(简体) ).
-   计划中列出的操作人员未执行(`Unsupported operator: <name>`) (中文(简体) ).
-   面向收集的操作员(`map`, (中文(简体) ), `filter`, (中文(简体) ), `exists`, (中文(简体) ), `all`使用时没有 `relation` 映射器,或带有 映射器宣布 `type: "one"` 地点 `type: "many"` 需要(例如: `map operator requires a relation mapping`) (中文(简体) ).
-   计划中的Lambda表达式有误(例如缺少一个可变的操作结果) `Lambda variable must have a name`) (中文(简体) ).
-   值操作不符合预期类型,例如, `hasIntersection` 提供非阵列值.

及早弥补这些错误有助于使适配器和你的Cerbos政策保持同步.

## 限制

-   `exists_one` 而不是无声地贬低 `exists`。 。 。 .
-   收集上游中的集合表达式、来自羊肉的外文件引用以及否定无效的收集宏失败,因为 `$elemMatch` 无法保存其 CEL 范围界定和三值错误语义.
-   未列出的运算符 **支持的运算符** (例如搜索、模式、平面数学帮助器、原子数操作、复合键等)没有执行,将投掷 `Unsupported operator`。 。 。 .
-   翻译可能使用文档级别 `$expr`,但从不需要多阶段聚合管道.

## 常见问题

### @cerbos/orm-mongoose 是什么？

一个适配器库 赛博斯 查询计划\( E\)计划资源 API\)反应并将其转换为 乌鸦 过滤器。 这是脱口秀

### 如何安装 @cerbos/orm-mongoose？

在项目目录运行 npm install @cerbos/orm-mongoose，或使用 pnpm add / yarn add / bun add。

### @cerbos/orm-mongoose 支持 TypeScript 吗？

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

### @cerbos/orm-mongoose 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @cerbos/orm-mongoose 需要什么版本的 Node\.js？

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

### @cerbos/orm-mongoose 可以商用吗？

@cerbos/orm-mongoose 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @cerbos/orm-mongoose 的下载量有多少？

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

### @cerbos/orm-mongoose 还在维护吗？

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

