"Of calls about wifi issues, how many are 2.4GHz vs 5GHz, and what are the key issues?" One question bundles retrieval, aggregation, labeling and evidence — normally an OLAP engine plus a vector store, with ETL between them. In XERJ it is one POST /_search: slice, breakdown, metrics and evidence come back together.
SPLIT STACK = OLAP + VECTOR STORE + ETL, OR TWO ROUND TRIPS IN ONE ENGINE · SOURCES IN docs/case-studies/calltree-analytics →
query.knn retrieves the semantic slice; the aggs block computes the band split, key issues, CSAT percentile and handle-time average over that slice; size: 3 returns the evidence hits. Demonstrated live with real 768-dim vectors — XERJ stores and searches them, it does not embed, so retrieval quality is your embedding model's job (EmbeddingGemma is a stand-in for yours).
curl -s localhost:9200/conversations/_search -H 'Content-Type: application/json' -d '{
"query": { "knn": { "field": "vec", "query_vector": [/* embed("wifi issues...") */],
"k": 80, "num_candidates": 130 } },
"size": 3, "_source": ["band","issue","body"],
"aggs": { "by_band": { "terms": { "field": "band" }, "aggs": {
"key_issues": { "terms": { "field": "issue", "size": 4 } },
"csat": { "percentiles": { "field": "csat", "percents": [50] } },
"aht": { "avg": { "field": "handle_time_s" } } } } }
}'
ONE POST /_search · RC.6
"of calls about wifi issues, how many 2.4 vs 5GHz, and what are the key issues?" retrieved 80 nearest wifi calls; aggregated in the same request: 2.4GHz 29 (54%) csat_p50=4.0 aht=897s issues: channel-overlap, congestion, disconnects, legacy-device 5GHz 25 (46%) csat_p50=4.0 aht=924s issues: range, disconnects, congestion deep-research narrative (LLM over the retrieved examples): The key issue is that the 5GHz signal is weak in a nearby room, dropping to 2.4GHz and resulting in slower speeds.
RECORDED RUN · SEEDED-GENERATOR OUTPUT · 54 OF THE 80 CARRIED A WIFI BAND; THE 26 N/A ARE FILTERED CLIENT-SIDE · 03_deep_research.py
num_candidates is ignored, HNSW never serves it, and cost scales with corpus size × dims. Nothing here was timed.hits.total.value echoes k — the 80 is the request parameter coming back, not a corpus match count.significant_terms over a kNN slice returns empty, hybrid (RRF) + aggs is rejected with a 400, and kNN inside bool.filter returns no buckets. Use terms in-slice, or the two-step pattern.The question came from calltree.ai, who run AI over support interactions — a motivating party, not a customer. The walkthrough has the three runnable scripts, the recorded output and the scaling guide. XERJ on :9200 plus Ollama is the whole stack.
Send us your mapping and one deep-research question. We'll send back the single-request version — kNN + aggs over your schema — with the scripts to reproduce it.