# Aggregate

> Perform aggregation operations like count, sum, average, etc., on data within a collection using API Maker.

Source: https://docs.apimaker.dev/v1/examples/sys/db/aggregate.html

`g.sys.db.aggregate` calls the [aggregate schema API](https://docs.apimaker.dev/v1/docs/apis-all/schema-apis/auto-generated-schema-based-aggregate-api.html) of any table from your code, with the same headers and query parameters as over HTTP. It returns the data, or the whole envelope when `true` is passed as the second argument.

## MongoDB Simple aggregate
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[{
        "$limit": 2
    }]
});
```

## MongoDB headers
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[{
        "$limit": 2
    }],
    headers: {
        "x-am-authorization": "TOKEN"
    }
});
```

## MongoDB Basic aggregation
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[[
        {
            "$group": {
                "_id": "$_id",
                "total": {
                    "$sum": "$customer_id"
                }
            }
        },
        {
            "$match": {
                "total": {
                    "$gt": 1
                }
            }
        },
        {
            "$sort": {
                "total": -1
            }
        },
        {
            "$count": "CountValue"
        }
    ]]
});
```

## MongoDB $project stage
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "full_name": {
                    "$toLower": "$first_name"
                }
            }
        }
    ]
});
```

## MongoDB $addFields
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$addFields": {
                "full_name": {
                    "$concat": [
                        "$first_name",
                        " ",
                        "$last_name"
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $bucket
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$bucket": {
                "groupBy": "$price",
                "boundaries": [10000,20000,30000,40000,50000],
                "default": "Other",
                "output": {
                    "count": {
                        "$sum": 1
                    },
                    "product_details": {
                        "$push": {
                            "name": "$name",
                            "price": "$price"
                        }
                    }
                }
            }
        }
    ]
});
```

## MongoDB $facet with multiple $bucket
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$facet": {
                "price": [
                    {
                        "$bucket": {
                            "groupBy": "$price",
                            "boundaries": [10000,20000,30000,40000,50000,60000,70000,80000],
                            "default": "Other",
                            "output": {
                                "count": {
                                    "$sum": 1
                                },
                                "product_details": {
                                    "$push": {
                                        "name": "$name",
                                        "price": "$price"
                                    }
                                }
                            }
                        }
                    }
                ],
                "categories": [
                    {
                        "$bucket": {
                            "groupBy": "$category_id",
                            "boundaries": [10000,20000,30000,40000,50000,60000,70000,80000],
                            "default": "Other",
                            "output": {
                                "count": {
                                    "$sum": 1
                                },
                                "product_details": {
                                    "$push": {
                                        "name": "$name",
                                        "id": "$id",
                                        "category_id": "$category_id"
                                    }
                                }
                            }
                        }
                    }
                ]
            }
        }
    ]
});
```

## MongoDB $collStats, latencyStats > histograms, storageStats, count
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$collStats": {
                "latencyStats": {
                    "histograms": true
                },
                "storageStats": {},
                "count": {}
            }
        }
    ]
});
```

## MongoDB $collStats, latencyStats > histograms, storageStats, count
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$collStats": {
                "latencyStats": {
                    "histograms": true
                },
                "storageStats": {},
                "count": {}
            }
        }
    ]
});
```

## MongoDB $count
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$match": {
                "price": {
                    "$gt": 10000
                }
            }
        },
        {
            "$count": "price_gt_10000"
        }
    ]
});
```

## MongoDB $limit
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$limit": 2
        }
    ]
});
```

## MongoDB $lookup
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$lookup": {
                "from": "products",
                "localField": "customer_id",
                "foreignField": "owner_id",
                "as": "customer_data"
            }
        }
    ]
});
```

## MongoDB $match
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$match": {
                "first_name": "Bob"
            }
        }
    ]
});
```

## MongoDB $redact, $cond, if, then, else, $$DESCEND, $$PRUNE
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$redact": {
                "$cond": {
                    "if": {
                        "$eq": [
                            "$first_name",
                            "JOHNNY"
                        ]
                    },
                    "then": "$$DESCEND",
                    "else": "$$PRUNE"
                }
            }
        }
    ]
});
```

## MongoDB $replaceRoot, newRoot
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$replaceRoot": {
                "newRoot": {
                    "full_name": {
                        "$concat": [
                            "$first_name",
                            " ",
                            "$last_name"
                        ]
                    }
                }
            }
        }
    ]
});
```

## MongoDB $sample
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$sample": {
                "size": 2
            }
        }
    ]
});
```

## MongoDB $skip
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$skip": 2
        }
    ]
});
```

## MongoDB $sort
### ascending

**MongoDB $sort**

```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$sort": {
                "customer_id": 1
            }
        }
    ]
});
```
### descending

**MongoDB $sort**

```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$sort": {
                "customer_id": -1
            }
        }
    ]
});
```

## MongoDB $unwind, $sortByCount
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$unwind": "$ages"
        },
        {
            "$sortByCount": "$ages"
        }
    ]
});
```

## MongoDB $abs, $subtract
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "Grand_Total": {
                    "$abs": {
                        "$subtract": [
                            "$total",
                            "$tax"
                        ]
                    }
                }
            }
        }
    ]
});
```

## MongoDB $add
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "Grand_Total": {
                    "$add": [
                        "$price",
                        "$category_id"
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $ceil, $floor
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "ceilingValue": {
                    "$ceil": "$price"
                },
                "floorValue": {
                    "$floor": "$price"
                },
                "id": 1
            }
        }
    ]
});
```

## MongoDB $divide
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "pricePercentage": {
                    "$divide": [
                        "$price",
                        100
                    ]
                },
                "id": 1
            }
        }
    ]
});
```

## MongoDB $multiply
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "Grand_Total": {
                    "$multiply": [
                        "$price",
                        "$quantity"
                    ]
                },
                "id": 1
            }
        }
    ]
});
```

## MongoDB $arrayElemAt
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
          "$project": {
            "first": {
              "$arrayElemAt": [
                "$attribuites.color",
                1
              ]
            }
          }
        }
    ]
});
```

## MongoDB $filter
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
          "$project": {
            "ages": {
              "$filter": {
                "input": "$ages",
                "as": "age",
                "cond": {
                  "$gte": [
                    "$$age.age",
                    50
                  ]
                }
              }
            }
          }
        }
    ]
});
```

## MongoDB $in
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "customer_id": "$customer_id",
                "TravelingHobby": {
                    "$in": [
                        "traveling",
                        "$hobbies"
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $indexOfArray
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "customer_id": "$customer_id",
                "index": {
                    "$indexOfArray": [
                        "$ages.birth_year",
                        1971
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $isArray
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "isHobbyCricket": {
                    "$cond": {
                        "if": {
                            "$isArray": "$hobbies"
                        },
                        "then": {
                            "$in": [
                                "traveling",
                                "$hobbies"
                            ]
                        },
                        "else": "One or more fields is not an array."
                    }
                }
            }
        }
    ]
});
```

## MongoDB $map
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "integerValues": {
                    "$map": {
                        "input": "$distances",
                        "as": "decimalValue",
                        "in": {
                            "$trunc": "$$decimalValue"
                        }
                    }
                }
            }
        }
    ]
});
```

## MongoDB $reverseArray
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "reverseDistances": {
                    "$reverseArray": "$distances"
                }
            }
        }
    ]
});
```

## MongoDB $size
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "customer_id": 1,
                "address": 1,
                "numberOfHobbies": {
                    "$cond": {
                        "if": {
                            "$isArray": "$hobbies"
                        },
                        "then": {
                            "$size": "$hobbies"
                        },
                        "else": "NA"
                    }
                }
            }
        }
    ]
});
```

## MongoDB $and
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": "$id",
                "result": {
                    "$and": [
                        {
                            "$gt": [
                                "$price",
                                60000
                            ]
                        },
                        {
                            "$lt": [
                                "$category_id",
                                45000
                            ]
                        }
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $not
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": "$id",
                "result": {
                    "$not": [
                        {
                            "$gt": [
                                "$price",
                                30000
                            ]
                        }
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $or
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": "$id",
                "result": {
                    "$or": [
                        {
                            "$gt": [
                                "$price",
                                60000
                            ]
                        },
                        {
                            "$lt": [
                                "$category_id",
                                1000
                            ]
                        }
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $cmp
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "comparePrice": {
                    "$cmp": [
                        "$price",
                        42187
                    ]
                },
                "_id": 1
            }
        }
    ]
});
```

## MongoDB $eq
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "equalPrice": {
                    "$eq": [
                        "$price",
                        42187
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $gt
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "graterPrice": {
                    "$gt": [
                        "$price",
                        42187
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $gte
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "gePrice": {
                    "$gte": [
                        "$price",
                        42187
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $lt
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "graterPrice": {
                    "$lt": [
                        "$price",
                        42187
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $lte
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "gePrice": {
                    "$lte": [
                        "$price",
                        42187
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $ne
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "nePrice": {
                    "$ne": [
                        "$price",
                        42187
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $cond
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "price": 1,
                "discount": {
                    "$cond": {
                        "if": {
                            "$gt": [
                                "$price",
                                50000
                            ]
                        },
                        "then": 30,
                        "else": 10
                    }
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $ifNull
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "price": 1,
                "shipping": {
                    "$ifNull": [
                        "$shipping",
                        null
                    ]
                },
                "_id": 0
            }
        }
    ]
});
```

## MongoDB $switch
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "price": 1,
                "priceSummary": {
                    "$switch": {
                        "branches": [
                            {
                                "case": {
                                    "$eq": [
                                        "$price",
                                        50000
                                    ]
                                },
                                "then": "equals"
                            },
                            {
                                "case": {
                                    "$gt": [
                                        "$price",
                                        50000
                                    ]
                                },
                                "then": "greater than"
                            },
                            {
                                "case": {
                                    "$lt": [
                                        "$price",
                                        50000
                                    ]
                                },
                                "then": "less than"
                            }
                        ]
                    }
                }
            }
        }
    ]
});
```

## MongoDB $concat
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$project": {
                "id": 1,
                "name_Description": {
                    "$concat": [
                        "$name",
                        "_",
                        "$description"
                    ]
                }
            }
        }
    ]
});
```

## MongoDB $max
```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "mongodb", database: "inventory", collection: "customers",
    aggregateQuery:[
        {
            "$group": {
                "_id": "$price",
                "maxQuantity": {
                    "$max": "$quantity"
                }
            }
        }
    ]
});
```

## Structure

**Aggregate method**

```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "INSTANCE_NAME", database: 'DB_NAME', collection: "COLLECTION_NAME",
    aggregateQuery: [
        {
            "$match":
                {
                    "COLUMN_NAME": "VALUE"
                }
        }
    ],
    headers: {
        "x-am-response-case": "capitalCase", // noChange | camelCase | capitalCase | constantCase | dotCase | headerCase | noCase | paramCase | pascalCase | pathCase | sentenceCase | snakeCase
        "x-am-response-object-type": "make_flat", // no_action | make_flat
        "x-am-meta": "true", // true, false
        "x-am-internationalization": "USER_I18N_ID",
        "x-am-run-in-sandbox": "2",
        "x-am-content-type-response": "text/xml", // application/json | text/xml | text/yaml | text/plain | text/html | application/octet-stream
        "x-am-cache-control": "reset_cache", // no_action | reset_cache
        "x-am-get-encrypted-data": "get_only_encryption", // no_encryption | get_only_encryption | get_data_and_encryption
        "x-am-sandbox-timeout": "13000",
        "x-no-compression": "true", // true | false
        "x-am-encrypted-payload": "true", // user will send 'true', when payload is encrypted for transfer
        // Multi-tenant : the tenant of the request, each instance finds it in its own tenants table
        "x-am-tenant-username": "TENANT_USERNAME", // ex: acme
        // Authorization headers
        "x-am-authorization": "AUTHORIZATION_TOKEN",
        "x-am-user-authorization": "API_USER_TOKEN",
        "x-aws-authorization": "AWS_TOKEN",
        "x-google-authorization": "GOOGLE_TOKEN",
        "x-azure-authorization": "AZURE_TOKEN",
    },
});
```

## Multi-tenant
- `instance: "crm::acme"` works on the database of the tenant `acme` of the [multi-tenant](https://docs.apimaker.dev/v1/docs/features/multi-tenant.html) instance `crm`.
- With `instance: "crm"`, the call works on the database of the tenant of the request: a custom API called with the [x-am-tenant-username](https://docs.apimaker.dev/v1/docs/apis-all/header/requestHeader.html#x-am-tenant-username) header passes it on to the APIs it calls. A request without a tenant works on the structure database.

**Aggregate the customers of the tenant acme (MongoDB)**

```typescript
let aggregate = await g.sys.db.aggregate({
    instance: "crm::acme", database: "crm", collection: "customers",
    aggregateQuery: [{
        "$group": {
            "_id": "$city",
            "customers": { "$sum": 1 }
        }
    }]
});
```

## Related

- [Aggregate API](https://docs.apimaker.dev/v1/docs/apis-all/schema-apis/auto-generated-schema-based-aggregate-api.html) · [Generated API from code](https://docs.apimaker.dev/v1/examples/sys/db/gen/aggregateGen.html) · [The global object g](https://docs.apimaker.dev/v1/docs/pre-defined-terms/global-object-g.html)
