This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/unomi.git
The following commit(s) were added to refs/heads/master by this push:
new 429ea21d5 UNOMI-1022: Document IP range aggregates and how to read
aggregate results (#927)
429ea21d5 is described below
commit 429ea21d5ae6210f51559bfa914ab9feeb960b45
Author: Serge Huber <[email protected]>
AuthorDate: Tue Oct 27 10:34:37 2026 +0100
UNOMI-1022: Document IP range aggregates and how to read aggregate results
(#927)
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.../main/asciidoc/queries-and-aggregations.adoc | 107 +++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/manual/src/main/asciidoc/queries-and-aggregations.adoc
b/manual/src/main/asciidoc/queries-and-aggregations.adoc
index d2fe43fbc..d748e98c3 100644
--- a/manual/src/main/asciidoc/queries-and-aggregations.adoc
+++ b/manual/src/main/asciidoc/queries-and-aggregations.adoc
@@ -200,6 +200,25 @@ The above request will produce a similar that looks like
this:
You can see that we retrieve the count of newcomers aggregated by day.
+The `interval` parameter accepts the following values, in short or named form.
It defaults to a month (`1M`).
+
+[cols="1,1"]
+|===
+| Short form | Named form
+
+| `1s` | `Second`
+| `1m` | `Minute`
+| `1h` | `Hour`
+| `1d` | `Day`
+| `1w` | `Week`
+| `1M` | `Month`
+| `1q` | `Quarter`
+| `1y` | `Year`
+|===
+
+Other values, such as `2d` or `day`, are not supported. The optional `format`
parameter sets how the date of each
+bucket is written in the result keys, as in the `yyyy-MM-dd` keys above.
+
===== Date range
Date ranges make it possible to "bucket" dates, for example to regroup
profiles by their birth date as in the example
@@ -273,6 +292,9 @@ The resulting JSON response will look something like this:
}
----
+Each range includes its `from` date and excludes its `to` date. Set `from` or
`to` to `null` for a range that is open on
+that side. The same rules apply to numeric and IP ranges.
+
You can find more information about the date range formats here:
- Elasticsearch documentation:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-daterange-aggregation.html[Date
range aggregation (Elasticsearch current)]
- OpenSearch documentation:
https://docs.opensearch.org/docs/latest/aggregations/bucket/date-range/[Date
range aggregation (OpenSearch)]
@@ -352,6 +374,91 @@ This will produce an output that looks like this:
}
----
+Ranges may overlap: a value is counted in every range it falls in.
+
+===== IP range
+
+IP ranges make it possible to "bucket" IP addresses, for example to tell
internal visitors from external ones. IPv4 and
+IPv6 addresses are both supported. The property must be mapped as an `ip`
field in the search engine before its data
+is indexed. No property is mapped that way by default, so add that mapping
yourself for the property you aggregate on.
+
+Here's an example that groups sessions by a custom `properties.remoteIp`
property:
+
+[source,shell script]
+----
+curl -X POST http://localhost:8181/cxs/query/session/properties.remoteIp \
+--user "TENANT_ID:PRIVATE_KEY" \
+-H "Content-Type: application/json" \
+-d @- <<'EOF'
+{
+ "aggregate": {
+ "property": "properties.remoteIp",
+ "type": "ipRange",
+ "ipRanges": [
+ {
+ "key": "Internal",
+ "from": "10.0.0.0",
+ "to": "11.0.0.0"
+ },
+ {
+ "key": "Loopback",
+ "from": "127.0.0.0",
+ "to": "128.0.0.0"
+ },
+ {
+ "from": "192.168.0.0",
+ "to": "192.169.0.0"
+ }
+ ]
+ },
+ "condition": {
+ "type": "matchAllCondition",
+ "parameterValues": {}
+ }
+}
+EOF
+----
+
+This will produce an output that looks like this:
+
+[source,json]
+----
+{
+ "_all":2310,
+ "_filtered":2310,
+ "Internal":1207,
+ "Loopback":12,
+ "192.168.0.0-192.169.0.0":340,
+ "_missing":64
+}
+----
+
+A range without a `key` is reported as `from-to`, as for the last range above.
+
+==== Reading the results
+
+The result of an aggregate query is a JSON object that maps each bucket key to
the number of items in that bucket. A
+few keys starting with an underscore hold counts of their own:
+
+`_all`:: The number of items of the requested type in the current tenant.
Counting every item takes extra time, so it
+is not returned when the `optimizedQuery=true` query parameter is set (as in
+`POST /cxs/query/profile/properties.nbOfVisits?optimizedQuery=true`), nor for
`GET` aggregate queries.
+`_filtered`:: The number of items that match the condition. Without
`optimizedQuery=true`, it is only returned when the
+request has a condition.
+`_missing`:: The number of matching items that have no value for the
aggregated property. It is only returned when there
+are such items.
+
+The bucket keys depend on the aggregation type:
+
+* When the request has no `aggregate`, or one without a `type`, the keys are
the values of the property.
+* For a date aggregation, the keys are the dates of the buckets, written with
the `format` parameter when it is set.
+ Periods with no items between the first and the last bucket are included,
with a count of `0`.
+* For a range aggregation, the keys are the `key` of each range. A range
without a `key` is reported as `from-to`, with
+ `*` for an open side, for example `*-5.0` or `100.0-*`. Every range is
reported, even with a count of `0`.
+
+A bucket whose key is `_all`, `_filtered` or `_missing` is dropped, because
those keys are reserved for the counts
+above.
+
=== Scroll Queries
Scroll queries are useful when you need to retrieve large result sets
efficiently. Instead of retrieving all results at once,