---
title: "Collection"
description: "NocoBase Database Collection API：定义数据模型、字段、索引、关联，通过 db.collection() 配置。"
keywords: "Collection,数据模型,db.collection,字段定义,Database API,NocoBase"
---

# Collection

## 概览

`Collection` 用于定义系统中的数据模型，如模型名称、字段、索引、关联等信息。
一般通过 `Database` 实例的 `collection` 方法作为代理入口调用。

```javascript
const { Database } = require('@nocobase/database')

// 创建数据库实例
const db = new Database({...});

// 定义数据模型
db.collection({
  name: 'users',
  // 定义模型字段
  fields: [
    // 标量字段
    {
      name: 'name',
      type: 'string',
    },

    // 关联字段
    {
      name: 'profile',
      type: 'hasOne' // 'hasMany', 'belongsTo', 'belongsToMany'
    }
  ],
});
```

更多字段类型请参考 [Fields](/api/database/field)。

## 构造函数

**签名**

- `constructor(options: CollectionOptions, context: CollectionContext)`

**参数**

| 参数名                | 类型                                                        | 默认值 | 描述                                                                                   |
| --------------------- | ----------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------- |
| `options.name`        | `string`                                                    | -      | collection 标识                                                                        |
| `options.tableName?`  | `string`                                                    | -      | 数据库表名，如不传则使用 `options.name` 的值                                           |
| `options.fields?`     | `FieldOptions[]`                                            | -      | 字段定义，详见 [Field](./field)                                                        |
| `options.model?`      | `string \| ModelStatic<Model>`                              | -      | Sequelize 的 Model 类型，如果使用的是 `string`，则需要调用之前在 db 上注册过该模型名称 |
| `options.repository?` | `string \| RepositoryType`                                  | -      | 数据仓库类型，如果使用 `string`，则需要调用之前在 db 上注册过该仓库类型                |
| `options.sortable?`   | `string \| boolean \| { name?: string; scopeKey?: string }` | -      | 数据可排序字段配置，默认不排序                                                         |
| `options.autoGenId?`  | `boolean`                                                   | `true` | 是否自动生成唯一主键，默认为 `true`                                                    |
| `context.database`    | `Database`                                                  | -      | 所在的上下文环境数据库                                                                 |

**示例**

创建一张文章表：

```ts
const posts = new Collection(
  {
    name: 'posts',
    fields: [
      {
        type: 'string',
        name: 'title',
      },
      {
        type: 'double',
        name: 'price',
      },
    ],
  },
  {
    // 已存在的数据库实例
    database: db,
  },
);
```

## 实例成员

### `options`

数据表配置初始参数。与构造函数的 `options` 参数一致。

### `context`

当前数据表所属的上下文环境，目前主要是数据库实例。

### `name`

数据表名称。

### `db`

所属数据库实例。

### `filterTargetKey`

作为主键的字段名。

### `isThrough`

是否为中间表。

### `model`

匹配 Sequelize 的 Model 类型。

### `repository`

数据仓库实例。

## 字段配置方法

### `getField()`

获取数据表已定义对应名称的字段对象。

**签名**

- `getField(name: string): Field`

**参数**

| 参数名 | 类型     | 默认值 | 描述     |
| ------ | -------- | ------ | -------- |
| `name` | `string` | -      | 字段名称 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

const field = posts.getField('title');
```

### `setField()`

对数据表设置字段。

**签名**

- `setField(name: string, options: FieldOptions): Field`

**参数**

| 参数名    | 类型           | 默认值 | 描述                            |
| --------- | -------------- | ------ | ------------------------------- |
| `name`    | `string`       | -      | 字段名称                        |
| `options` | `FieldOptions` | -      | 字段配置，详见 [Field](./field) |

**示例**

```ts
const posts = db.collection({ name: 'posts' });

posts.setField('title', { type: 'string' });
```

### `setFields()`

对数据表批量设置多个字段。

**签名**

- `setFields(fields: FieldOptions[], resetFields = true): Field[]`

**参数**

| 参数名        | 类型             | 默认值 | 描述                            |
| ------------- | ---------------- | ------ | ------------------------------- |
| `fields`      | `FieldOptions[]` | -      | 字段配置，详见 [Field](./field) |
| `resetFields` | `boolean`        | `true` | 是否重置已存在的字段            |

**示例**

```ts
const posts = db.collection({ name: 'posts' });

posts.setFields([
  { type: 'string', name: 'title' },
  { type: 'double', name: 'price' },
]);
```

### `removeField()`

移除数据表已定义对应名称的字段对象。

**签名**

- `removeField(name: string): void | Field`

**参数**

| 参数名 | 类型     | 默认值 | 描述     |
| ------ | -------- | ------ | -------- |
| `name` | `string` | -      | 字段名称 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.removeField('title');
```

### `resetFields()`

重置（清空）数据表的字段。

**签名**

- `resetFields(): void`

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.resetFields();
```

### `hasField()`

判断数据表是否已定义对应名称的字段对象。

**签名**

- `hasField(name: string): boolean`

**参数**

| 参数名 | 类型     | 默认值 | 描述     |
| ------ | -------- | ------ | -------- |
| `name` | `string` | -      | 字段名称 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.hasField('title'); // true
```

### `findField()`

查找数据表中符合条件的字段对象。

**签名**

- `findField(predicate: (field: Field) => boolean): Field | undefined`

**参数**

| 参数名      | 类型                        | 默认值 | 描述     |
| ----------- | --------------------------- | ------ | -------- |
| `predicate` | `(field: Field) => boolean` | -      | 查找条件 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.findField((field) => field.name === 'title');
```

### `forEachField()`

遍历数据表中的字段对象。

**签名**

- `forEachField(callback: (field: Field) => void): void`

**参数**

| 参数名     | 类型                     | 默认值 | 描述     |
| ---------- | ------------------------ | ------ | -------- |
| `callback` | `(field: Field) => void` | -      | 回调函数 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.forEachField((field) => console.log(field.name));
```

## 索引配置方法

### `addIndex()`

添加数据表索引。

**签名**

- `addIndex(index: string | string[] | { fields: string[], unique?: boolean,[key: string]: any })`

**参数**

| 参数名  | 类型                                                         | 默认值 | 描述                 |
| ------- | ------------------------------------------------------------ | ------ | -------------------- |
| `index` | `string \| string[]`                                         | -      | 需要配置索引的字段名 |
| `index` | `{ fields: string[], unique?: boolean, [key: string]: any }` | -      | 完整配置             |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.addIndex({
  fields: ['title'],
  unique: true,
});
```

### `removeIndex()`

移除数据表索引。

**签名**

- `removeIndex(fields: string[])`

**参数**

| 参数名   | 类型       | 默认值 | 描述                     |
| -------- | ---------- | ------ | ------------------------ |
| `fields` | `string[]` | -      | 需要移除索引的字段名组合 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
  indexes: [
    {
      fields: ['title'],
      unique: true,
    },
  ],
});

posts.removeIndex(['title']);
```

## 表配置方法

### `remove()`

删除数据表。

**签名**

- `remove(): void`

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

posts.remove();
```

## 数据库操作方法

### `sync()`

同步数据表定义到数据库。除了 Sequelize 中默认的 `Model.sync` 的逻辑，还会一并处理关系字段对应的数据表。

**签名**

- `sync(): Promise<void>`

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

await posts.sync();
```

### `existsInDb()`

判断数据表是否存在于数据库中。

**签名**

- `existsInDb(options?: Transactionable): Promise<boolean>`

**参数**

| 参数名                 | 类型          | 默认值 | 描述     |
| ---------------------- | ------------- | ------ | -------- |
| `options?.transaction` | `Transaction` | -      | 事务实例 |

**示例**

```ts
const posts = db.collection({
  name: 'posts',
  fields: [
    {
      type: 'string',
      name: 'title',
    },
  ],
});

const existed = await posts.existsInDb();

console.log(existed); // false
```

### `removeFromDb()`

**签名**

- `removeFromDb(): Promise<void>`

**示例**

```ts
const books = db.collection({
  name: 'books',
});

// 同步书籍表到数据库
await db.sync();

// 删除数据库中的书籍表
await books.removeFromDb();
```
