---
title: "HyperLogLog data type"
description: "Aerospike HyperLogLog (HLL) guide: estimating cardinality, set unions, intersections, and similarity in large datasets."
---

# HyperLogLog data type

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

The HyperLogLog bin data type gives you _estimated_ counts of members in a large dataset for your application to form fast, reasonable approximations of members in the union or intersection between multiple HyperLogLog bins. HyperLogLog’s estimates are a balance between complete accuracy and efficient savings in space and speed in dealing with extremely large datasets.

Operations across HLL bin types are processed on the server side. Only results are returned to the client.

In this discussion, the words “set” and “dataset” are used with the meaning from mathematical set theory, not the Aerospike concept of sets.

## Set theory fundamental background

The HyperLogLog data returned to your application is based on some basic ideas from set theory. The article [Probabilistic: Definition, Models, and Theory Explained](https://www.statisticshowto.com/probabilistic/) gives some brief background information.

### Union of sets

 ![Union](https://aerospike.com/docs/_astro/union.kDl3tyEa_bUNdA.png)

### Intersection of sets

 ![Intersection](https://aerospike.com/docs/_astro/intersection.4u5Oybr6_ZX8HIc.png)

## Business use cases

The HyperLogLog data type is useful for any problem where your underlying data cannot give you exact answers. Some business use cases include deriving probable answers for the following needs:

### Bank fraud

Count the number of suspicious indicators related to an account and its transactions to determine in real-time the probability of fraud of an incoming transaction.

### Ad campaign scope

Given the user segments an ad is targeting, what is the approximate number of people who will see the ad?

### Online sales conversion rate

By comparing user cohorts and their interest in adjacent items, how many possible customers who log in to the website will finally end up purchasing something in the same user session? In multiple sessions?

## HyperLogLog data and data modeling

As with all Aerospike data types, your own values define the underlying HyperLogLog data. You need to model your data on values that have some intrinsic relationship so that you can derive counts of membership in individual data sets or the union or intersection of multiple datasets. In colloquial words, you must “compare apples to apples but not apples to oranges”.

Continuing the example of user segmentation in online ad campaigns, you might have records representing user segments, each with a HyperLogLog bin to represent the membership in the segment. With the data returned by batch reading the bins of multiple segments, you can ask the server for the count of the members in an intersection of multiple segments. For example:

-   All the people who love basketball. This is one segment, represented in an HLL bin of one record.
-   All the people who like the Golden State Warriors, another segment.
-   All the people who also like hats as a fashion accessory.

The meaning of the HLL bins is specific to the use case of identifying users as parts of audience segments, and counting those segments and intersections and unions between them for ad campaigns.

As a baseline for comparison, you can compare between records with HyperLogLog bins representing the same kind of data set specific to your use case. At a minimum, you need to define two HyperLogLog data sets so that their relationships can be explored. The exact meaning of the data is up to you.

-   Continuing the example of bank fraud in the use cases described above, you have records that you are certain show fraud. With the data returned by HyperLogLog, your application can find the probability that other records match the pattern of the identified records.
-   Continuing the example of online sales conversion rate in the use cases described above, the following need to be defined:
    -   Date/time of login to the website
    -   Date/time of purchase

## What the HyperLogLog data type returns to your application

The HyperLogLog returns the following information to your application:

-   The estimated size of a set.
-   The estimated cardinality of the union of multiple sets.
-   The estimated similarity of multiple sets.
-   The estimated cardinality of the intersection of multiple sets.
-   The estimated union of multiple sets. This estimate is returned as a HyperLogLog data type.

### Calculating the size of the returned data

Because the HyperlogLog data type is for working with large data sets, the data it returns can also be large. You need to be aware of the storage cost of a HyperLogLog bin. For small sets a data type other than HyperLogLog might suffice, but for large data sets the unchanging storage size is extremely advantageous.

-   Each HLL contains 11 bytes of metadata and an array of 2**n\_index\_bits** registers.
    
-   Each register contains 6 bits of hll\_val and n\_minhash\_bits bits of minhash\_val. The size of the registers is rounded up to the nearest byte.  
    

sizeof(HLL) = 11 + roundUpToByte(2**n\_index\_bits** × (6 + n\_minhash\_bits))

For general guidelines on bin overheads, see [Linux Capacity Planning](https://aerospike.com/docs/database/manage/planning/capacity).

## Error Bounds

| **Operation** | **Error type** | **Error formula** | **Notes** |
| --- | --- | --- | --- |
| **`refresh_count`**  
**`get_count`**  
**`get_union_count`** | Relative | 1.042n\_index\_bits\\frac{1.04}{\\sqrt{2^{n\\\_index\\\_bits}}}2n\_index\_bits​1.04​ | Increasing bits exponentially reduces  
relative error. For example, 4 bits → 26%,  
10 bits → 3.25%, 16 bits → 0.41%. |
| **`get_similarity`** | Absolute | n\_minhash\_bits≥log⁡2(6e⋅t)n\\\_minhash\\\_bits \\geq \\log\_2\\left(\\frac{6}{e \\cdot t}\\right)n\_minhash\_bits≥log2​(e⋅t6​)  
  
n\_index\_bits≥log⁡2(e−2)n\\\_index\\\_bits \\geq \\log\_2(e^{-2})n\_index\_bits≥log2​(e−2) | Select bits to meet target error `e`,  
and tune parameters based on  
desired accuracy and similarity  
threshold. |
| **`get_intersect_count`** | Absolute or  
Relative | 12n\_minhash\_bits\\frac{1}{\\sqrt{2^{n\\\_minhash\\\_bits}}}2n\_minhash\_bits​1​ | Use enough minhash bits for  
reliable intersections:  
\- Stable if `n_minhash_bits` > 0  
\- Unstable if `n_minhash_bits` = 0 |

## Performance

| **Symbol** | **Description** |
| :-- | :-- |
| C | Cost of memcpy (added to all modifies). |
| E | Number of entries passed to the operation. |
| K | Number of HLLs being operated on. |
| M | Number of minhash bits. |
| N | Number of index bits. |
| R | Cost of storage read (applies to any transaction - only once per transaction). |
| S | Size of a HLL in bytes (M + 1) × 2N |
| W | Cost of writing to storage (applies to any modify transaction - only once per transaction). |

| **Operation** | **HyperLogLog (n\_minhash\_bits = 0)** | **HyperMinHash (n\_minhash\_bits > 0)** |
| :-- | :-- | :-- |
| `init` | S | S |
| `add` | E | E |
| `set_union` | K × S | K × S |
| `refresh_count` | S | S |
| `fold` | K × S | K × S |
| `get_count` | S | S |
| `get_union` | K × S | K × S |
| `get_union_count` | K × S | K × S |
| `get_intersect_count` | K! × S  
0 ≤ K ≤ 2 | K × S + S |
| `get_similarity` | K! × S  
0 ≤ K ≤ 2 | K × S + S |
| `describe` | 1 | 1 |

## Operations

HyperLogLog relies on the following APIs the clients applications use:

| Name | Value | Description |
| :-- | :-- | :-- |
| `create_only` | `0x01` | Disallow updating an existing value of this bin. |
| `update_only` | `0x02` | Disallow creation of a new Blob bin. |
| `no_fail` | `0x04` | Allow a set of operations to proceed if an individual operation would fail due to a policy violation. |
| `allow_fold` | `0X08` | Allow the resulting set to be the minimum of provided **n\_index\_bits**. For intersect\_counts and similarity, allow the usage of less precise HLL algorithms when **n\_minhash\_bits** of all participating sets do not match. |

## Modify operations

#### `add`

`create_only` `no_fail`

Adds values to HLL set. If HLL bin does not exist, use n\_index\_bits to create HLL bin.

```python
add(policy, bin_name, items, n_index_bits)
```

---

Adds values to HLL set. If HLL bin does not exist, use n\_index\_bits and n\_minhash\_bits to create HLL bin.

```python
add_mh(policy, bin_name, items, n_index_bits, n_minhash_bits)
```

---

Adds values to HLL set. The HLL bin must already exist.

```python
update(policy, bin_name, items)
```

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `policy` | `library_specific` | 
HLL modify policy.

 |
| `bin_name` | `string` | 

Name of bin.

 |
| `n_index_bits` | `integer` | 

Number of index bits. Must be between 4 and 16 inclusive.

 |
| `n_minhash_bits` | `integer` | 

Number of minhash bits. Must be between 4 and 51 inclusive.

 |

Returns: `integer`

Examples: Add members to an HLL

Add user IDs to an audience-segment HLL. If the bin does not yet exist it is created with 10 index bits. The return value is the estimated number of elements that caused the internal count to change (new unique members). Adding the same user ID again does not increase the count.

Code sample: -   [Java](#tab-panel-655)
-   [Python](#tab-panel-656)
-   [Go](#tab-panel-657)
-   [C](#tab-panel-658)
-   [C#](#tab-panel-659)
-   [Node.js](#tab-panel-660)

```java
// Add user IDs to a "visitors" HLL, creating it with 10 index bits if needed

List<Value> users = Arrays.asList(

    Value.get("user-1001"), Value.get("user-1002"), Value.get("user-1003")

);

Record record = client.operate(null, key,

    HLLOperation.add(HLLPolicy.Default, "visitors", users, 10)

);

// record.getInt("visitors") → estimated new unique items added
```

```python
# Add user IDs to a "visitors" HLL, creating it with 10 index bits if needed

_, _, bins = client.operate(key, [

    hll_operations.hll_add(

        "visitors",

        ["user-1001", "user-1002", "user-1003"],

        index_bit_count=10,

    )

])

# bins["visitors"] → estimated new unique items added
```

```go
users := []as.Value{

    as.NewStringValue("user-1001"),

    as.NewStringValue("user-1002"),

    as.NewStringValue("user-1003"),

}

record, err := client.Operate(nil, key,

    as.HLLAddOp(as.DefaultHLLPolicy(), "visitors", users, 10, -1),

)

// record.Bins["visitors"] → estimated new unique items added
```

```c
as_arraylist items;

as_arraylist_inita(&items, 3);

as_arraylist_append_str(&items, "user-1001");

as_arraylist_append_str(&items, "user-1002");

as_arraylist_append_str(&items, "user-1003");

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_add(&ops, "visitors", NULL, NULL,

    (as_list*)&items, 10);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```csharp
// Add user IDs to a "visitors" HLL, creating it with 10 index bits if needed

IList users = new List<Value> {

    Value.Get("user-1001"), Value.Get("user-1002"), Value.Get("user-1003")

};

Record record = client.Operate(null, key,

    HLLOperation.Add(HLLPolicy.Default, "visitors", users, 10)

);

// record.GetInt("visitors") → estimated new unique items added
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const result = await client.operate(key, [

    hll.add('visitors', ['user-1001', 'user-1002', 'user-1003'], 10)

])

// result.bins.visitors → estimated new unique items added
```

---

#### `fold`

```python
fold(bin_name, n_index_bits)
```

Description: Folds the HLL bin to the specified n\_index\_bits.

Fails if existing HLL has n\_minhash\_bits set to non-zero.

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin.

 |
| `n_index_bits` | `integer` | 

Number of index bits. Must be between 4 and 16 inclusive.

 |

Returns: `none`

Examples: Fold to fewer index bits

Reduce the precision of an HLL bin from its current index bit count down to a lower value. This shrinks storage at the cost of wider error bounds. Folding is useful when combining HLLs that were created with different index bit counts — fold the higher one down before calling [`set_union`](#set_union). Folding is irreversible and fails if the HLL has minhash bits set.

Code sample: -   [Java](#tab-panel-661)
-   [Python](#tab-panel-662)
-   [Go](#tab-panel-663)
-   [C](#tab-panel-664)
-   [C#](#tab-panel-665)
-   [Node.js](#tab-panel-666)

```java
// Fold a 12-bit HLL down to 8 index bits

Record record = client.operate(null, key,

    HLLOperation.fold("visitors", 8)

);
```

```python
# Fold a 12-bit HLL down to 8 index bits

_, _, bins = client.operate(key, [

    hll_operations.hll_fold("visitors", index_bit_count=8)

])
```

```go
record, err := client.Operate(nil, key,

    as.HLLFoldOp("visitors", 8),

)
```

```c
as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_fold(&ops, "visitors", NULL, 8);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```csharp
// Fold a 12-bit HLL down to 8 index bits

Record record = client.Operate(null, key,

    HLLOperation.Fold("visitors", 8)

);
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const result = await client.operate(key, [

    hll.fold('visitors', 8)

])
```

---

#### `init`

`create_only` `update_only` `no_fail`

Initializes or resets a standard HyperLogLog.

```python
init(policy, bin_name, n_index_bits)
```

---

Initializes or resets a HyperLogLog with minhash information (see [HyperMinHash](https://arxiv.org/abs/1710.08436)) bits to improve accuracy of intersection and similarity estimates.

```python
init(policy, bin_name, n_index_bits, n_minhash_bits)
```

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `policy` | `library_specific` | 
HLL modify policy.

 |
| `bin_name` | `string` | 

Name of bin.

 |
| `n_index_bits` | `integer` | 

Number of index bits. It must be between 4 and 16 inclusive.

 |
| `n_minhash_bits` | `integer` | 

Number of minhash bits. It must be between 4 and 51 inclusive.

 |
| `hll_bits + minhash_bits` | `integer` | 

The sum of index and minhash bits, it must be less than or equal to 64 bits inclusive.

 |

Returns: `none`

Examples: Initialize an HLL bin

Create an HLL bin on a record that represents an ad-campaign audience segment. Use 10 index bits for roughly 3% relative error on cardinality estimates. After initialization the bin is empty (count 0) and ready to receive members via [`add`](#add).

Code sample: -   [Java](#tab-panel-667)
-   [Python](#tab-panel-668)
-   [Go](#tab-panel-669)
-   [C](#tab-panel-670)
-   [C#](#tab-panel-671)
-   [Node.js](#tab-panel-672)

```java
// Initialize an HLL bin with 10 index bits

Record record = client.operate(null, key,

    HLLOperation.init(HLLPolicy.Default, "visitors", 10)

);
```

```python
# Initialize an HLL bin with 10 index bits

_, _, bins = client.operate(key, [

    hll_operations.hll_init("visitors", index_bit_count=10)

])
```

```go
record, err := client.Operate(nil, key,

    as.HLLInitOp(as.DefaultHLLPolicy(), "visitors", 10, -1),

)
```

```c
as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_init(&ops, "visitors", NULL, NULL, 10);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```csharp
// Initialize an HLL bin with 10 index bits

Record record = client.Operate(null, key,

    HLLOperation.Init(HLLPolicy.Default, "visitors", 10)

);
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const result = await client.operate(key, [

    hll.init('visitors', 10)

])
```

---

#### `refresh_count`

```python
refresh_count(bin_name)
```

Description: Updates the cached count (if stale) and returns the count. For relative error see [Error Bounds](#error-bounds).

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin.

 |

Returns: `integer`

Examples: Refresh a stale count

After a batch of [`add`](#add) operations the cached count may be stale. Call `refresh_count` to recompute and return the current cardinality estimate. The value returned is equivalent to [`get_count`](#get_count) but also persists the refreshed count inside the HLL for subsequent reads.

Code sample: -   [Java](#tab-panel-673)
-   [Python](#tab-panel-674)
-   [Go](#tab-panel-675)
-   [C](#tab-panel-676)
-   [C#](#tab-panel-677)
-   [Node.js](#tab-panel-678)

```java
Record record = client.operate(null, key,

    HLLOperation.refreshCount("visitors")

);

long count = record.getLong("visitors");
```

```python
_, _, bins = client.operate(key, [

    hll_operations.hll_refresh_count("visitors")

])

count = bins["visitors"]
```

```go
record, err := client.Operate(nil, key,

    as.HLLRefreshCountOp("visitors"),

)

count := record.Bins["visitors"]
```

```c
as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_refresh_count(&ops, "visitors", NULL);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);

int64_t count = as_record_get_int64(rec, "visitors", 0);
```

```csharp
Record record = client.Operate(null, key,

    HLLOperation.RefreshCount("visitors")

);

long count = record.GetLong("visitors");
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const result = await client.operate(key, [

    hll.refreshCount('visitors')

])

const count = result.bins.visitors
```

---

#### `set_union`

`create_only` `update_only` `no_fail`

```python
set_union(policy, bin_name, hlls)
```

Description: Sets union of specified list of HLLs with HLL bin.

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `policy` | `library_specific` | 
HLL modify policy.

 |
| `bin_name` | `string` | 

Name of bin.

 |
| `hlls` | `list` | 

List of HLL objects.

 |

Returns: `none`

Examples: Merge audience segments

Merge one or more external HLL values into a bin. A common pattern is to read the raw HLL bytes from another record (for example a different audience segment) and merge them into the current record’s HLL. After `set_union` the bin contains every member from all contributing HLLs, and [`get_count`](#get_count) returns the estimated cardinality of the combined set.

Code sample: -   [Java](#tab-panel-679)
-   [Python](#tab-panel-680)
-   [Go](#tab-panel-681)
-   [C](#tab-panel-682)
-   [C#](#tab-panel-683)
-   [Node.js](#tab-panel-684)

```java
// Read the HLL from a second segment record

Record other = client.get(null, otherKey, "visitors");

Value.HLLValue otherHll = other.getHLLValue("visitors");

// Merge it into the current record's HLL

Record record = client.operate(null, key,

    HLLOperation.setUnion(HLLPolicy.Default, "visitors",

        Arrays.asList(otherHll))

);
```

```python
# Read the HLL from a second segment record

_, _, other = client.get(other_key)

other_hll = other["visitors"]

# Merge it into the current record's HLL

_, _, bins = client.operate(key, [

    hll_operations.hll_set_union("visitors", [other_hll])

])
```

```go
otherRec, err := client.Get(nil, otherKey, "visitors")

otherHll := otherRec.Bins["visitors"].(as.HLLValue)

record, err := client.Operate(nil, key,

    as.HLLSetUnionOp(as.DefaultHLLPolicy(), "visitors",

        []as.HLLValue{otherHll}),

)
```

```c
// Read HLL bytes from another record

as_record* other = NULL;

aerospike_key_get(&as, &err, NULL, &other_key, &other);

as_bytes* other_hll = as_record_get_bytes(other, "visitors");

as_arraylist hll_list;

as_arraylist_inita(&hll_list, 1);

as_arraylist_append_bytes(&hll_list, other_hll);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_set_union(&ops, "visitors", NULL, NULL,

    (as_list*)&hll_list);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```csharp
// Read the HLL from a second segment record

Record other = client.Get(null, otherKey, "visitors");

Value.HLLValue otherHll = new Value.HLLValue(

    (byte[])other.GetValue("visitors"));

// Merge it into the current record's HLL

Record record = client.Operate(null, key,

    HLLOperation.SetUnion(HLLPolicy.Default, "visitors",

        new List<Value.HLLValue> { otherHll })

);
```

```javascript
const Aerospike = require('aerospike')

const hll_ops = Aerospike.hll

// Read the HLL from a second segment record

const other = await client.get(otherKey, ['visitors'])

const otherHll = other.bins.visitors

// Merge it into the current record's HLL

const result = await client.operate(key, [

    hll_ops.setUnion('visitors', [otherHll])

])
```

---

## Read operations

#### `describe`

```python
describe(bin_name)
```

Description: List containing the HLL bin’s configured `n_index_bits` and `n_minhash_bits`.

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin.

 |

Returns: `list`

Examples: Inspect HLL configuration

Returns a two-element list: `[n_index_bits, n_minhash_bits]`. Use this to verify an HLL’s precision settings before performing operations like [`fold`](#fold) or [`set_union`](#set_union) that require matching configurations.

Code sample: -   [Java](#tab-panel-685)
-   [Python](#tab-panel-686)
-   [Go](#tab-panel-687)
-   [C](#tab-panel-688)
-   [C#](#tab-panel-689)
-   [Node.js](#tab-panel-690)

```java
Record record = client.operate(null, key,

    HLLOperation.describe("visitors")

);

List<?> desc = record.getList("visitors");

long indexBits = (long)desc.get(0);

long minhashBits = (long)desc.get(1);
```

```python
_, _, bins = client.operate(key, [

    hll_operations.hll_describe("visitors")

])

index_bits, minhash_bits = bins["visitors"]
```

```go
record, err := client.Operate(nil, key,

    as.HLLDescribeOp("visitors"),

)

desc := record.Bins["visitors"].([]interface{})

indexBits := desc[0]   // n_index_bits

minhashBits := desc[1] // n_minhash_bits
```

```c
as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_describe(&ops, "visitors", NULL);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);

as_list* desc = as_record_get_list(rec, "visitors");

int64_t index_bits = as_list_get_int64(desc, 0);

int64_t minhash_bits = as_list_get_int64(desc, 1);
```

```csharp
Record record = client.Operate(null, key,

    HLLOperation.Describe("visitors")

);

IList desc = record.GetList("visitors");

long indexBits = (long)desc[0];

long minhashBits = (long)desc[1];
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const result = await client.operate(key, [

    hll.describe('visitors')

])

const [indexBits, minhashBits] = result.bins.visitors
```

---

#### `get_count`

```python
get_count(bin_name)
```

Description: Estimate of the number of unique entries in the HLL set. For relative error see [Error Bounds](#error-bounds).

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin.

 |

Returns: `integer`

Examples: Estimate audience size

After adding user IDs with [`add`](#add), read the estimated cardinality. The relative error depends on `n_index_bits` — for example, 10 bits gives roughly 3.25% relative error. `get_count` uses the cached count and does not recompute it; call [`refresh_count`](#refresh_count) first if the bin has been modified since the last count.

Code sample: -   [Java](#tab-panel-691)
-   [Python](#tab-panel-692)
-   [Go](#tab-panel-693)
-   [C](#tab-panel-694)
-   [C#](#tab-panel-695)
-   [Node.js](#tab-panel-696)

```java
Record record = client.operate(null, key,

    HLLOperation.getCount("visitors")

);

long estimated = record.getLong("visitors");
```

```python
_, _, bins = client.operate(key, [

    hll_operations.hll_get_count("visitors")

])

estimated = bins["visitors"]
```

```go
record, err := client.Operate(nil, key,

    as.HLLGetCountOp("visitors"),

)

estimated := record.Bins["visitors"]
```

```c
as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_get_count(&ops, "visitors", NULL);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);

int64_t estimated = as_record_get_int64(rec, "visitors", 0);
```

```csharp
Record record = client.Operate(null, key,

    HLLOperation.GetCount("visitors")

);

long estimated = record.GetLong("visitors");
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const result = await client.operate(key, [

    hll.getCount('visitors')

])

const estimated = result.bins.visitors
```

---

#### `get_intersect_count`

```python
get_intersect_count(bin_name, hlls)
```

Description: Estimate of the number of elements that would be contained by the intersection of these HLL objects and the HLL bin. For relative error see [Error Bounds](#error-bounds).

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin containing an HLL value.

 |
| `hlls` | `list` | 

List of HLL objects. If HLL minhash bits are 0, maximum 2 objects in list, otherwise may be greater than 2.

 |

Returns: `integer`

Examples: Estimate audience overlap

Given two audience-segment records — “basketball fans” and “Warriors fans” — estimate how many users appear in both. Read the raw HLL bytes from the second record and pass them to `get_intersect_count` on the first. The result is the estimated cardinality of the intersection. When `n_minhash_bits` is 0, the list may contain at most 2 HLL objects.

Code sample: -   [Java](#tab-panel-697)
-   [Python](#tab-panel-698)
-   [Go](#tab-panel-699)
-   [C](#tab-panel-700)
-   [C#](#tab-panel-701)
-   [Node.js](#tab-panel-702)

```java
// Read the Warriors-fans HLL

Record warriors = client.get(null, warriorsKey, "visitors");

Value.HLLValue warriorsHll = warriors.getHLLValue("visitors");

// Estimate overlap with basketball-fans HLL

Record record = client.operate(null, basketballKey,

    HLLOperation.getIntersectCount("visitors",

        Arrays.asList(warriorsHll))

);

long overlap = record.getLong("visitors");
```

```python
# Read the Warriors-fans HLL

_, _, warriors = client.get(warriors_key)

warriors_hll = warriors["visitors"]

# Estimate overlap with basketball-fans HLL

_, _, bins = client.operate(basketball_key, [

    hll_operations.hll_get_intersect_count("visitors", [warriors_hll])

])

overlap = bins["visitors"]
```

```go
warriorsRec, err := client.Get(nil, warriorsKey, "visitors")

warriorsHll := warriorsRec.Bins["visitors"].(as.HLLValue)

record, err := client.Operate(nil, basketballKey,

    as.HLLGetIntersectCountOp("visitors",

        []as.HLLValue{warriorsHll}),

)

overlap := record.Bins["visitors"]
```

```c
// Read the Warriors-fans HLL

as_record* warriors = NULL;

aerospike_key_get(&as, &err, NULL, &warriors_key, &warriors);

as_bytes* warriors_hll = as_record_get_bytes(warriors, "visitors");

as_arraylist hll_list;

as_arraylist_inita(&hll_list, 1);

as_arraylist_append_bytes(&hll_list, warriors_hll);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_get_intersect_count(&ops, "visitors", NULL,

    (as_list*)&hll_list);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &basketball_key, &ops, &rec);

int64_t overlap = as_record_get_int64(rec, "visitors", 0);
```

```csharp
// Read the Warriors-fans HLL

Record warriors = client.Get(null, warriorsKey, "visitors");

Value.HLLValue warriorsHll = new Value.HLLValue(

    (byte[])warriors.GetValue("visitors"));

// Estimate overlap with basketball-fans HLL

Record record = client.Operate(null, basketballKey,

    HLLOperation.GetIntersectCount("visitors",

        new List<Value.HLLValue> { warriorsHll })

);

long overlap = record.GetLong("visitors");
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

// Read the Warriors-fans HLL

const warriors = await client.get(warriorsKey, ['visitors'])

const warriorsHll = warriors.bins.visitors

// Estimate overlap with basketball-fans HLL

const result = await client.operate(basketballKey, [

    hll.getIntersectCount('visitors', [warriorsHll])

])

const overlap = result.bins.visitors
```

---

#### `get_similarity`

```python
get_similarity(bin_name, hlls)
```

Description: Estimate of the similarity (or [Jaccard Index](https://en.wikipedia.org/wiki/Jaccard_index)) of these HLL objects and the HLL bin. For absolute error see [Error Bounds](#error-bounds).

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin containing an HLL value.

 |
| `hlls` | `list` | 

List of HLL objects. If HLL minhash bits are 0, maximum 2 objects in the list, otherwise may be greater than 2.

 |

Returns: `float`

Examples: Measure audience similarity

The Jaccard similarity index is `|A ∩ B| / |A ∪ B|`, ranging from 0 (disjoint) to 1 (identical). Use `get_similarity` to estimate how much two audience segments overlap relative to their combined size. Higher accuracy requires non-zero `n_minhash_bits` at initialization time — see [Error Bounds](#error-bounds).

Code sample: -   [Java](#tab-panel-703)
-   [Python](#tab-panel-704)
-   [Go](#tab-panel-705)
-   [C](#tab-panel-706)
-   [C#](#tab-panel-707)
-   [Node.js](#tab-panel-708)

```java
Record other = client.get(null, otherKey, "visitors");

Value.HLLValue otherHll = other.getHLLValue("visitors");

Record record = client.operate(null, key,

    HLLOperation.getSimilarity("visitors",

        Arrays.asList(otherHll))

);

double similarity = record.getDouble("visitors");
```

```python
_, _, other = client.get(other_key)

other_hll = other["visitors"]

_, _, bins = client.operate(key, [

    hll_operations.hll_get_similarity("visitors", [other_hll])

])

similarity = bins["visitors"]
```

```go
otherRec, err := client.Get(nil, otherKey, "visitors")

otherHll := otherRec.Bins["visitors"].(as.HLLValue)

record, err := client.Operate(nil, key,

    as.HLLGetSimilarityOp("visitors",

        []as.HLLValue{otherHll}),

)

similarity := record.Bins["visitors"]
```

```c
as_record* other = NULL;

aerospike_key_get(&as, &err, NULL, &other_key, &other);

as_bytes* other_hll = as_record_get_bytes(other, "visitors");

as_arraylist hll_list;

as_arraylist_inita(&hll_list, 1);

as_arraylist_append_bytes(&hll_list, other_hll);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_get_similarity(&ops, "visitors", NULL,

    (as_list*)&hll_list);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```csharp
Record other = client.Get(null, otherKey, "visitors");

Value.HLLValue otherHll = new Value.HLLValue(

    (byte[])other.GetValue("visitors"));

Record record = client.Operate(null, key,

    HLLOperation.GetSimilarity("visitors",

        new List<Value.HLLValue> { otherHll })

);

double similarity = record.GetDouble("visitors");
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const other = await client.get(otherKey, ['visitors'])

const otherHll = other.bins.visitors

const result = await client.operate(key, [

    hll.getSimilarity('visitors', [otherHll])

])

const similarity = result.bins.visitors
```

---

#### `get_union`

```python
get_union(bin_name, hlls)
```

Description: Returns an HLL object that is the union of all specified HLL objects in the hlls list with the HLL bin.

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin.

 |
| `hlls` | `list` | 

List of HLL objects.

 |

Returns: `HLL`

Examples: Read-only union of audience segments

Unlike [`set_union`](#set_union), `get_union` does **not** modify the bin. It returns a new HLL value representing the union of the bin and the provided HLL list. The returned bytes can be used client-side — for example, passed to another record’s `set_union`, or used locally with [`get_union_count`](#get_union_count) in the same `operate` call.

Code sample: -   [Java](#tab-panel-709)
-   [Python](#tab-panel-710)
-   [Go](#tab-panel-711)
-   [C](#tab-panel-712)
-   [C#](#tab-panel-713)
-   [Node.js](#tab-panel-714)

```java
Record other = client.get(null, otherKey, "visitors");

Value.HLLValue otherHll = other.getHLLValue("visitors");

Record record = client.operate(null, key,

    HLLOperation.getUnion("visitors",

        Arrays.asList(otherHll))

);

Value.HLLValue unionHll = record.getHLLValue("visitors");
```

```python
_, _, other = client.get(other_key)

other_hll = other["visitors"]

_, _, bins = client.operate(key, [

    hll_operations.hll_get_union("visitors", [other_hll])

])

union_hll = bins["visitors"]  # raw HLL bytes
```

```go
otherRec, err := client.Get(nil, otherKey, "visitors")

otherHll := otherRec.Bins["visitors"].(as.HLLValue)

record, err := client.Operate(nil, key,

    as.HLLGetUnionOp("visitors",

        []as.HLLValue{otherHll}),

)

unionHll := record.Bins["visitors"].(as.HLLValue)
```

```c
as_record* other = NULL;

aerospike_key_get(&as, &err, NULL, &other_key, &other);

as_bytes* other_hll = as_record_get_bytes(other, "visitors");

as_arraylist hll_list;

as_arraylist_inita(&hll_list, 1);

as_arraylist_append_bytes(&hll_list, other_hll);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_get_union(&ops, "visitors", NULL,

    (as_list*)&hll_list);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);

as_bytes* union_hll = as_record_get_bytes(rec, "visitors");
```

```csharp
Record other = client.Get(null, otherKey, "visitors");

Value.HLLValue otherHll = new Value.HLLValue(

    (byte[])other.GetValue("visitors"));

Record record = client.Operate(null, key,

    HLLOperation.GetUnion("visitors",

        new List<Value.HLLValue> { otherHll })

);

byte[] unionHll = (byte[])record.GetValue("visitors");
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const other = await client.get(otherKey, ['visitors'])

const otherHll = other.bins.visitors

const result = await client.operate(key, [

    hll.getUnion('visitors', [otherHll])

])

const unionHll = result.bins.visitors // raw HLL Buffer
```

---

#### `get_union_count`

```python
get_union_count(bin_name, hlls)
```

Description: Estimate of the number of elements that would be contained by the union of these HLL objects and the HLL bin. For relative error see [Error Bounds](#error-bounds).

Arguments: | Name | Type | Description |
| --- | --- | --- |
| `bin_name` | `string` | 
Name of bin.

 |
| `hlls` | `list` | 

List of HLL objects.

 |

Returns: `integer`

Examples: Estimate combined reach

Given two audience-segment HLLs — for example “basketball fans” and “hat enthusiasts” — estimate the total number of distinct users across both segments. This is the estimated cardinality of the union, useful for ad-campaign reach projections. The bin itself is not modified.

Code sample: -   [Java](#tab-panel-715)
-   [Python](#tab-panel-716)
-   [Go](#tab-panel-717)
-   [C](#tab-panel-718)
-   [C#](#tab-panel-719)
-   [Node.js](#tab-panel-720)

```java
Record other = client.get(null, otherKey, "visitors");

Value.HLLValue otherHll = other.getHLLValue("visitors");

Record record = client.operate(null, key,

    HLLOperation.getUnionCount("visitors",

        Arrays.asList(otherHll))

);

long totalReach = record.getLong("visitors");
```

```python
_, _, other = client.get(other_key)

other_hll = other["visitors"]

_, _, bins = client.operate(key, [

    hll_operations.hll_get_union_count("visitors", [other_hll])

])

total_reach = bins["visitors"]
```

```go
otherRec, err := client.Get(nil, otherKey, "visitors")

otherHll := otherRec.Bins["visitors"].(as.HLLValue)

record, err := client.Operate(nil, key,

    as.HLLGetUnionCountOp("visitors",

        []as.HLLValue{otherHll}),

)

totalReach := record.Bins["visitors"]
```

```c
as_record* other = NULL;

aerospike_key_get(&as, &err, NULL, &other_key, &other);

as_bytes* other_hll = as_record_get_bytes(other, "visitors");

as_arraylist hll_list;

as_arraylist_inita(&hll_list, 1);

as_arraylist_append_bytes(&hll_list, other_hll);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_hll_get_union_count(&ops, "visitors", NULL,

    (as_list*)&hll_list);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);

int64_t total_reach = as_record_get_int64(rec, "visitors", 0);
```

```csharp
Record other = client.Get(null, otherKey, "visitors");

Value.HLLValue otherHll = new Value.HLLValue(

    (byte[])other.GetValue("visitors"));

Record record = client.Operate(null, key,

    HLLOperation.GetUnionCount("visitors",

        new List<Value.HLLValue> { otherHll })

);

long totalReach = record.GetLong("visitors");
```

```javascript
const Aerospike = require('aerospike')

const hll = Aerospike.hll

const other = await client.get(otherKey, ['visitors'])

const otherHll = other.bins.visitors

const result = await client.operate(key, [

    hll.getUnionCount('visitors', [otherHll])

])

const totalReach = result.bins.visitors
```

---