# Aggregate Built-ins

| Function | Description | Meta |
| --- | --- | --- |
| `count` | `n := count(collection)`  Count takes a collection or string and returns the number of elements (or characters) in it.  **Arguments:**  `collection` (any<string, array\[any\], object\[any: any\], set\[any\]>)  the set/array/object/string to be counted  **Returns:**  `n` (number)  the count of elements, key/val pairs, or characters, respectively. | Wasm |
| `max` | `n := max(collection)`  Returns the maximum value in a collection.  **Arguments:**  `collection` (any<array\[any\], set\[any\]>)  the set or array to be searched  **Returns:**  `n` (any)  the maximum of all elements | Wasm |
| `min` | `n := min(collection)`  Returns the minimum value in a collection.  **Arguments:**  `collection` (any<array\[any\], set\[any\]>)  the set or array to be searched  **Returns:**  `n` (any)  the minimum of all elements | Wasm |
| `product` | `n := product(collection)`  Multiplies elements of an array or set of numbers  **Arguments:**  `collection` (any<array\[number\], set\[number\]>)  the set or array of numbers to multiply  **Returns:**  `n` (number)  the product of all elements | Wasm |
| `sort` | `n := sort(collection)`  Returns a sorted array.  **Arguments:**  `collection` (any<array\[any\], set\[any\]>)  the array or set to be sorted  **Returns:**  `n` (array\[any\])  the sorted array | Wasm |
| `sum` | `n := sum(collection)`  Sums elements of an array or set of numbers.  **Arguments:**  `collection` (any<array\[number\], set\[number\]>)  the set or array of numbers to sum  **Returns:**  `n` (number)  the sum of all elements | Wasm |

## Examples

### `count`

`count` returns the number of elements in an array, set, or object, or the number of runes in a string. It's the simplest building block for size-based policy checks (e.g. _"reject any Pod with more than 10 containers"_).

Counting items in a list

A common policy pattern is rejecting a request whose collection has too many or too few items, e.g. an Ingress with no rules, or a Pod that asks for more than `n` containers.

`count` works on arrays, sets, objects, and strings, so the same builtin covers all four shapes.

policy.rego

```
package play# An arraycontainers := ["nginx", "sidecar", "logger"]container_count := count(containers)# A set (duplicates don't count twice)unique_ports := {80, 443, 80}unique_port_count := count(unique_ports)# An object (counts the keys)labels := {	"app":  "web",	"tier": "frontend",	"team": "platform",}label_count := count(labels)# A string (counts the runes)name := "kubernetes"name_length := count(name)# A typical guard: reject if the input has more containers than allowed.deny contains msg if {	count(input.spec.containers) > 10	msg := sprintf("too many containers: %d", [count(input.spec.containers)])}
```

Output

{
  "container\_count": 3,
  "containers": \[
    "nginx",
    "sidecar",
    "logger"
  \],
  "deny": \[\],
  "label\_count": 3,
  "labels": {
    "app": "web",
    "team": "platform",
    "tier": "frontend"
  },
  "name": "kubernetes",
  "name\_length": 10,
  "unique\_port\_count": 2,
  "unique\_ports": \[
    80,
    443
  \]
}

input.json

```
{  "spec": {    "containers": [      "nginx",      "sidecar"    ]  }}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcInNwZWNcIjoge1xuICAgIFwiY29udGFpbmVyc1wiOiBbXG4gICAgICBcIm5naW54XCIsXG4gICAgICBcInNpZGVjYXJcIlxuICAgIF1cbiAgfVxufSIsImQiOiJ7fSIsInAiOiJwYWNrYWdlIHBsYXlcblxuIyBBbiBhcnJheVxuY29udGFpbmVycyA6PSBbXCJuZ2lueFwiLCBcInNpZGVjYXJcIiwgXCJsb2dnZXJcIl1cblxuY29udGFpbmVyX2NvdW50IDo9IGNvdW50KGNvbnRhaW5lcnMpXG5cbiMgQSBzZXQgKGR1cGxpY2F0ZXMgZG9uJ3QgY291bnQgdHdpY2UpXG51bmlxdWVfcG9ydHMgOj0gezgwLCA0NDMsIDgwfVxuXG51bmlxdWVfcG9ydF9jb3VudCA6PSBjb3VudCh1bmlxdWVfcG9ydHMpXG5cbiMgQW4gb2JqZWN0IChjb3VudHMgdGhlIGtleXMpXG5sYWJlbHMgOj0ge1xuXHRcImFwcFwiOiAgXCJ3ZWJcIixcblx0XCJ0aWVyXCI6IFwiZnJvbnRlbmRcIixcblx0XCJ0ZWFtXCI6IFwicGxhdGZvcm1cIixcbn1cblxubGFiZWxfY291bnQgOj0gY291bnQobGFiZWxzKVxuXG4jIEEgc3RyaW5nIChjb3VudHMgdGhlIHJ1bmVzKVxubmFtZSA6PSBcImt1YmVybmV0ZXNcIlxuXG5uYW1lX2xlbmd0aCA6PSBjb3VudChuYW1lKVxuXG4jIEEgdHlwaWNhbCBndWFyZDogcmVqZWN0IGlmIHRoZSBpbnB1dCBoYXMgbW9yZSBjb250YWluZXJzIHRoYW4gYWxsb3dlZC5cbmRlbnkgY29udGFpbnMgbXNnIGlmIHtcblx0Y291bnQoaW5wdXQuc3BlYy5jb250YWluZXJzKSA+IDEwXG5cdG1zZyA6PSBzcHJpbnRmKFwidG9vIG1hbnkgY29udGFpbmVyczogJWRcIiwgW2NvdW50KGlucHV0LnNwZWMuY29udGFpbmVycyldKVxufVxuIn0=)

### `sum`

`sum` adds up the elements of an array or set of numbers. A common use is budgeting a quota across multiple Kubernetes resources from a single admission policy.

Limiting total replicas across deployments

`sum` adds up the elements of an array or set of numbers. A common use is budgeting a quota across multiple Kubernetes resources from a single admission policy, e.g. capping the total `replicas` requested across the deployments in a namespace.

policy.rego

```
package play# Replicas requested by every Deployment in the input.replicas := [d.spec.replicas | some d in input.deployments]total_replicas := sum(replicas)deny contains msg if {	total_replicas > input.budget	msg := sprintf(		"total replicas %d exceeds namespace budget of %d",		[total_replicas, input.budget],	)}
```

Output

{
  "deny": \[
    "total replicas 12 exceeds namespace budget of 10"
  \],
  "replicas": \[
    3,
    4,
    5
  \],
  "total\_replicas": 12
}

input.json

```
{  "budget": 10,  "deployments": [    {      "spec": {        "replicas": 3      }    },    {      "spec": {        "replicas": 4      }    },    {      "spec": {        "replicas": 5      }    }  ]}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcImJ1ZGdldFwiOiAxMCxcbiAgXCJkZXBsb3ltZW50c1wiOiBbXG4gICAge1xuICAgICAgXCJzcGVjXCI6IHtcbiAgICAgICAgXCJyZXBsaWNhc1wiOiAzXG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICBcInNwZWNcIjoge1xuICAgICAgICBcInJlcGxpY2FzXCI6IDRcbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIFwic3BlY1wiOiB7XG4gICAgICAgIFwicmVwbGljYXNcIjogNVxuICAgICAgfVxuICAgIH1cbiAgXVxufSIsImQiOiJ7fSIsInAiOiJwYWNrYWdlIHBsYXlcblxuIyBSZXBsaWNhcyByZXF1ZXN0ZWQgYnkgZXZlcnkgRGVwbG95bWVudCBpbiB0aGUgaW5wdXQuXG5yZXBsaWNhcyA6PSBbZC5zcGVjLnJlcGxpY2FzIHwgc29tZSBkIGluIGlucHV0LmRlcGxveW1lbnRzXVxuXG50b3RhbF9yZXBsaWNhcyA6PSBzdW0ocmVwbGljYXMpXG5cbmRlbnkgY29udGFpbnMgbXNnIGlmIHtcblx0dG90YWxfcmVwbGljYXMgPiBpbnB1dC5idWRnZXRcblx0bXNnIDo9IHNwcmludGYoXG5cdFx0XCJ0b3RhbCByZXBsaWNhcyAlZCBleGNlZWRzIG5hbWVzcGFjZSBidWRnZXQgb2YgJWRcIixcblx0XHRbdG90YWxfcmVwbGljYXMsIGlucHV0LmJ1ZGdldF0sXG5cdClcbn1cbiJ9)