> For the complete documentation index, see [llms.txt](https://codemash.gitbook.io/codemash/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codemash.gitbook.io/codemash/cloud/database/aggregates/new.md).

# Create an aggregate

Write a MongoDB aggregation pipeline, test it on live data and save it as an aggregate.

**Where:** Database → Aggregates → **Add New** · `/projects/<project>/db/aggregates/new`

## Before you start

* The collection exists, is published and has some records — see [Create a schema](/codemash/cloud/database/collections/create-schema.md).
* You need `database:create` on the aggregates of that schema. **TEST** needs `database:create` or `database:update` there, plus `database:read` on the collection and on every collection the pipeline joins.

## Steps

1. Open **Database → Aggregates** and press **Add New**. The editor is titled **Add New Aggregate**.

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-db787ce9811b77bf6086a2c6f8db330bdd1f0905%2Faggregates-new-1.png?alt=media" alt="Add New Aggregate: an empty Schema picker, Name and Description fields, a note about @Model tokens with a Details link, an empty pipeline editor, Cancel and Save"><figcaption><p>The empty aggregate editor.</p></figcaption></figure>
2. Fill in the fields:

   | Field       | Required | What it does                                                                                                                               | Example                                          |
   | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ |
   | Schema      | yes      | The collection the pipeline runs on. A **Sample record** panel then shows its first record, with **Copy**, so you can see the field names. | `books`                                          |
   | Name        | yes      | The name in the list.                                                                                                                      | `Books per genre`                                |
   | Description | no       | Free text.                                                                                                                                 | `How many books and pages we have in each genre` |

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-a43483035ccdac09bcdd30ab28b219a28109719a%2Faggregates-new-2.png?alt=media" alt="Add New Aggregate with Schema books, Name Books per genre, Description, and the Sample record panel showing the first books record (The Silk Roads, 636 pages, history)"><figcaption><p>Schema, name and the sample record.</p></figcaption></figure>
3. Write the pipeline in the editor — standard MongoDB stages as a JSON array:

   ```json
   [
     { "$group": { "_id": "$genre", "books": { "$sum": 1 }, "pages": { "$sum": "$pages" } } },
     { "$sort": { "books": -1 } }
   ]
   ```

   Strict JSON checking is off on purpose, so you can use `@Model` tokens that your app fills at run time, for example `{ "$match": { "pages": { "$gt": @Model.minPages } } }`.
4. Press **TEST**. The answer from live data opens below as a JSON tree (`root: [] 3 items`). When the pipeline has `@Model` tokens, a dialog first asks for a test value for each one.

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-b45d296b7abed7845bdcc710cdfd4930901f5a23%2Faggregates-new-3.png?alt=media" alt="The pipeline editor with the $group and $sort stages, the TEST button and the result root: [] 3 items; Cancel and Save"><figcaption><p>The pipeline and its TEST result.</p></figcaption></figure>
5. Press **Save**. **Cancel** leaves without saving.

## Result

Cloud goes back to **Database → Aggregates**, and the aggregate is listed with its id (`maggr_5W9f2eefrp0I3UwXVxDP2o`). Your app runs it with `executeAggregate` and that id.

<figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-4ab95c9502f43383434127df5141be20a27713ad%2Faggregates-list-1.png?alt=media" alt="Aggregates list with maggr_5W9f2eefrp0I3UwXVxDP2o, Books per genre, books"><figcaption><p>The saved aggregate.</p></figcaption></figure>

When the project has an AI assistant set up, **Create using AI Chat** at the top of the editor opens it: it reads the schema's fields, drafts the pipeline into the editor and leaves saving to you.

## Change or remove it later

* **Edit** — click the id in the list — see [Edit an aggregate](/codemash/cloud/database/aggregates/edit.md).
* **Delete** — **Delete** in the editor — see [Delete an aggregate](/codemash/cloud/database/aggregates/delete.md).

## Do it from code

```ts
const pipeline = JSON.stringify([
  { $group: { _id: '$genre', books: { $sum: 1 } } },
  { $sort: { books: -1 } },
]);
const test = await norbix.hub.database.testDatabaseAggregate({ collectionName: 'books', pipeline });
console.log(test.result); // the answer from live data
const { id } = await norbix.hub.database.saveDatabaseAggregate({
  schemaId: 'sch_7lPCzWonEvTQsheGDCaKq', // books
  displayName: 'Genres by size',
  pipeline,
});
```

```sh
norbix hub database aggregate test --collectionName books --pipeline '[{"$group":{"_id":"$genre","books":{"$sum":1}}}]'
```

The client setup is on the [Database page](/codemash/cloud/database.md#use-it-from-code). API: [Test Database Aggregate](/codemash/api-reference/database/aggregates/test-database-aggregate.md) · [Save Database Aggregate](/codemash/api-reference/database/aggregates/save-database-aggregate.md)
