How to exclude terms in nested composite aggregation - elasticsearch

I am using composite aggregation on nested fields in elasticsearch but I want to exclude some terms from the result.
This aggregation is working:
{
"size": 0,
"geo": {
"communication": {
"nested": {
"path": "geo"
},
"aggs": {
"table": {
"composite": {
"size": 1000,
"sources": [
{"stk1": {"terms": {"field": "geo.src"}}},
{"stk2": {"terms": {"field": "geo.dest"}}}
]
}
}
}
}
}
}
But I want to exclude some terms from stk2,
{
"size": 0,
"aggs": {
"geo": {
"nested": {
"path": "geo"
},
"aggs": {
"table": {
"composite": {
"size": 1000,
"sources": [
{"stk1": {"terms": {"field": "geo.src"}}},
{"stk2": {"terms": {"field": "geo.dest", "exclude":"cancel"}}}
]
}
}
}
}
}
}
The above query is not working.
UPDATE 1: The result should omit only the array elements and not the entire document containing "cancel".
I am using elastic v6.7

I'd suggest using a query to exclude those documents:
{
"size": 0,
"aggs": {
"geo": {
"nested": {
"path": "geo"
}
},
"aggs": {
"filter": {
"bool": {
"must_not": {
"prefix": {
"geo.dest": "cancel"
}
}
}
},
"aggs": {
"table": {
"composite": {
"size": 10,
"sources": [
{
"stk1": {
"terms": {
"field": "geo.src"
}
}
},
{
"stk2": {
"terms": {
"field": "geo.dest"
}
}
}
]
}
}
}
}
}
}

Related

ELASTICSERCH - Inner_hits aggregations

I am trying to do an aggregation of the {"wildcare": {"data.addresses.ces.cp": "maria*"},
{"macth": { "data.addresses.ces.direction": "rodriguez"}} fields, but it does not return the results of the query.
{ "_source": "created_at",
"size": 1,
"sort": [
{
"created_at.keyword": {
"order": "desc"
}
}
],
"query": {
"nested": {
"path": "data.addresses",
"inner_hits": {
},
"query": {
"nested": {
"path": "data.addresses.ces",
"query":
{"wildcare": {"data.addresses.ces.cp": "maria*"},
{"macth": { "data.addresses.ces.direction": "rodriguez"}}
}
}
}
}
}
How can I perform an aggregation that returns the values ​​of the query, and not all the values ​​of the JSON?
In case the aggregations don't support inner_hits, how could I get wildcare and macth in aggs?
You need to repeat the filter conditions in the aggregation part so that the aggregation only runs on the selected nested documents:
{
"_source": "created_at",
"size": 1,
"sort": [
{
"created_at.keyword": {
"order": "desc"
}
}
],
"query": {
"nested": {
"path": "data.addresses",
"inner_hits": {},
"query": {
"nested": {
"path": "data.addresses.ces",
"query": {
"bool": {
"filter": [
{
"wildcard": {
"data.addresses.ces.cp": "maria*"
}
},
{
"match": {
"data.addresses.ces.direction": "rodriguez"
}
}
]
}
}
}
}
}
},
"aggs": {
"addresses": {
"nested": {
"path": "data.addresses"
},
"aggs": {
"ces": {
"nested": {
"path": "data.addresses.ces"
},
"aggs": {
"query": {
"filter": {
"bool": {
"filter": [
{
"wildcard": {
"data.addresses.ces.cp": "maria*"
}
},
{
"match": {
"data.addresses.ces.direction": "rodriguez"
}
}
]
}
},
"aggs": {
"cp": {
"terms": {
"field": "data.addresses.ces.cp"
}
},
"direction": {
"terms": {
"field": "data.addresses.ces.direction"
}
}
}
}
}
}
}
}
}
}

How to order serial_diff aggregation result in Elasticsearch?

I have build a query based on serial_diff aggregation. I am trying to sort the result based on the result of the serial_diff agg. I am struggling to get the result in order, below.
GET db/_search
{
"size": 0,
"query": {
"bool": {
"must": [
{
"terms": {
"Name": [
"q"
]
}
}
],
"filter": [
{
"range": {
"ts": {
"gte": "2020-03-09T09:00:00.000Z",
"lte": "2020-03-09T12:40:00.000Z",
"format": "date_optional_time"
}
}
}
]
}
},
"aggs": {
"sourceNameCount": {
"cardinality": {
"field": "sourceName"
}
},
"sourceName": {
"terms": {
"size": 100,
"field": "sourceName"
},
"aggs": {
"timeseries": {
"date_histogram": {
"field": "ts",
"min_doc_count": 1,
"interval": "15m",
"order": {
"_key": "asc"
}
},
"aggs": {
"the_sum":{
"avg":{
"field": "libVal"
}
},
"ts_diff":{
"serial_diff": {
"buckets_path": "the_sum",
"lag": 1
}
}
}
}
}
}
}
}

FIlter is not being applied to aggregation

I'm trying to get the billing of a product selled by a specific user, but it seems that the query is not being applied to the sum aggregation.
Could someone help me, please?
{
"query": {
"bool": {
"filter": [
{ "term": { "seller": 1 } },
{"term": { "product": 2 } }
]
}
},
"size": 0,
"aggs": {
"product": {
"terms": {
"field": "product"
},
"aggregations": {
"billing": {
"sum": {
"field": "price"
}
},
"aggregation": {
"bucket_sort": {
"sort": [
{
"billing": {
"order": "desc"
}
}
]
}
}
}
}
}
}
Try nesting your existing aggregations within another terms aggregation on "seller".
{
"query": {
"bool": {
"filter": [
{
"term": {
"seller": 1
}
},
{
"term": {
"product": 2
}
}
]
}
},
"size": 0,
"aggs": {
"seller": {
"terms": {
"field": "seller",
"size": 1
},
"aggs": {
"product": {
"terms": {
"field": "product",
"size": 1
},
"aggregations": {
"billing": {
"sum": {
"field": "price"
}
},
"aggregation": {
"bucket_sort": {
"sort": [
{
"billing": {
"order": "desc"
}
}
]
}
}
}
}
}
}
}
}

Elasticsearch applying filters to aggregation

I'm trying to build a facets system using Elasticsearch to display the number of documents which match a query.
I'm currently doing this query on /_search?search_type=count:
{
"query": {
"query_string": {
"query": "status:(1|2) AND categories:A"
}
},
"aggs": {
"all_products": {
"global": {},
"aggs": {
"countries": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "country"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"categories": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "category"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"statuses": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "status"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
}
}
}
}
}
the documents have the following structure:
{
"id": 123,
"name": "Title",
"categories": ["A", "B", "C"],
"country": "United Kingdom",
"status": 1
}
so the output I'm looking for should be:
Country
UK: 123
USA: 1000
Category
Motors: 23
Fashion: 1100
Status
Active: 1120
Not Active: 3
I don't know how to filter properly the aggregations, because right now they are counting all the document in the specified field, without considering the query status:(1|2) AND categories:A.
The elastic version is 1.7.2.
You simply need to remove global aggregation since it is not influenced by the query, just move your countries, categories and statuses aggregations at the top level like this:
{
"query": {
"query_string": {
"query": "status:(1|2) AND categories:A"
}
},
"aggs": {
"countries": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "country"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"categories": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "category"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"statuses": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "status"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
}
}
}
Fabio. Ill see Your post on upwork, i have worked example for ES 2.4, may be it help You.
"index": "{{YOUR ELASTIC INDEX}}",
"type": "{{YOUR ELASTIC TYPE}}",
"body": {
"aggs": {
"trademarks": { // aggs NAME
"terms": {
"field": "id", // field name in ELASTIC base
"size": 100 // count of results YOU need
}
},
"materials": { //another aggs NAME
"terms": {
"field": "materials.name", // field name in ELASTIC base
"size": 100 / count of results YOU need
}
},
"certificate": {
"terms": {
"field": "certificate_type_id",
"size": 100
}
},
"country": {
"terms": {
"field": "country.id",
"size": 100
}
},
"price": {
"stats": {
"field": "price"
}
}
},
"from": 0, // start from
"size": 20, // results count
"query": {
"constant_score": {
"filter": { //apply filter
"bool": {
"should": [{ // all categories You need to show
"term": {
"categories": "10142"
}
}, {
"term": {
"categories": "10143"
}
}, {
"term": {
"categories": "10144"
}
}, {
"term": {
"categories": "10145"
}
}, {
"term": {
"categories": "12957"
}
}, {
"term": {
"categories": "13968"
}
}, {
"term": {
"categories": "14353"
}
}, {
"term": {
"categories": "16954"
}
}, {
"term": {
"categories": "18243"
}
}, {
"term": {
"categories": "10141"
}
}],
"must": [{ // if you want another filed to filter for example filter BY field trademark_id
"bool": {
"should": [{
"term": {
"trademark_id": "2872"
}
}, {
"term": {
"trademark_id": "2879"
}
}, {
"term": {
"trademark_id": "2914"
}
}]
}
}, {
"bool": { // filter by PRICE
"must": [{
"range": {
"price": {
"from": 5.97,
"to": 15752.69
}
}
}]
}
}]
}
}
}
},
"sort": { //here SORT BY desc or asc
"updated_at": "desc" //updated_at - field from ES base
}
}

Filter OUT matching documents in elasticsearch with aggregation

I'm attempting to query statistics about documents in elasticsearch with the following query. The problem is that I'm trying to ignore documents with certain values for the field logger, but I can't figure out how. The query below selects all the right documents into the set, but it doesn't exclude documents with the undesirable values.
Any suggestions very welcome.
{
"query": {
"bool": {
"filter": {
"bool": {
"must_not": {
"terms": {
"logger": [
"experimentsplitsegmentlogger_errors",
"ExperimentLogger"
]
}
}
}
},
"must_not": {
"terms": {
"logger": [
"experimentsplitsegmentlogger_errors",
"ExperimentLogger"
]
}
},
"must": {
"exists": {
"field": "count"
}
}
}
},
"aggs": {
"keys": {
"filter": {
"bool": {
"must_not": {
"terms": {
"logger": [
"experimentsplitsegmentlogger_errors",
"ExperimentLogger"
]
}
}
}
},
"terms": {
"field": "logger"
},
"aggs": {
"hostnames": {
"terms": {
"field": "hostname"
},
"aggs": {
"pids": {
"terms": {
"field": "pid"
},
"aggs": {
"time_stats": {
"stats": {
"field": "timestamp"
}
},
"count_stats": {
"stats": {
"field": "count"
}
}
}
}
}
}
}
}
},
"size": 0
}
This should work for you as I removed filter and terms from the same level of aggregation.
{
"query": {
"bool": {
"filter": {
"not": {
"terms": {
"logger": [
"experimentsplitsegmentlogger_errors",
"ExperimentLogger"
]
}
}
},
"must": {
"exists": {
"field": "count"
}
}
}
},
"aggs": {
"keys": {
"terms": {
"field": "logger"
}
}
},
"size": 0
}

Resources