I'm trying to query a nested field's inner hits for cardinality, however it's not working for field aliases (where resellers.price is an alias). I'm using an elastic search example to show this
GET /products/_search
{
"aggs": {
"resellers": {
"nested": {
"path": "resellers"
},
"aggs": {
"unique_prices": {
"cardinality": { "field": "resellers.price" }
}
}
}
}
}
Adding a working example with index data, mapping, search query and search result
Index Mapping:
{
"mappings": {
"properties": {
"resellers": {
"type": "nested",
"properties": {
"cost": {
"type": "integer"
},
"price": {
"type": "alias",
"path": "resellers.cost"
}
}
}
}
}
}
Index Data:
{
"resellers": {
"cost": 200
}
}
{
"resellers": {
"cost": 100
}
}
{
"resellers": {
"cost": 200
}
}
Search Query:
{
"size": 0,
"aggs": {
"resellers": {
"nested": {
"path": "resellers"
},
"aggs": {
"unique_prices": {
"cardinality": {
"field": "resellers.price"
}
}
}
}
}
}
Search Result:
"aggregations": {
"resellers": {
"doc_count": 3,
"unique_prices": {
"value": 2
}
}
}
Related
I have the below aggregations query.
{
"aggs": {
"selected_brand": {
"filter": {
"term": {
"brandId": "b1d28821-3730-4266-8f55-eb69596004fb"
}
}
},
"sponsorshipSets": {
"nested": {
"path": "sponsorshipSets"
},
"aggs": {
"sponsorships": {
"nested": {
"path": "sponsorshipSets.sponsorships"
},
"aggs": {
"count": {
"value_count": {
"field": "sponsorshipSets.sponsorships.id"
}
}
}
}
}
}
}
}
The response is the below.
{
"hits": {
"total": {
"value": 2980,
"relation": "eq"
}
},
"aggregations": {
"selected_brand": {
"doc_count": 314
},
"sponsorshipSets": {
"doc_count": 2635,
"sponsorships": {
"doc_count": 1076,
"count": {
"value": 1076
}
}
}
}
}
The response shows the count of sponsorship documents is 1076, now I want to retrieve the documents these documents and tried with the below query.
{
"query": {
"bool": {
"must": {
"nested": {
"path": "sponsorshipSets",
"query": {
"nested": {
"path": "sponsorshipSets.sponsorships",
"query": {
"bool": {
"must_not": [
{
"match": {
"sponsorshipSets.sponsorships": "null"
}
}
]
}
}
}
}
}
},
"filter": [
{
"term": {
"brandId": "b1d28821-3730-4266-8f55-eb69596004fb"
}
}
]
}
}
}
The interesting thing for the second query is the hits below is only 82.
"hits": {
"total": {
"value": 82,
"relation": "eq"
},
What I really want is to retrieve the count of all the sponsorshipSets.sponsorships documents that are not null or not exist. SponsorshipSets can be missing as well.
Find below the abbreviated template.
{
"index_patterns": "campaigns*",
"order": 4,
"version": 4,
"aliases": {
"campaigns": {
}
},
"settings": {
"number_of_shards": 5
},
"mappings": {
"dynamic": "false",
"properties": {
"brandId": {
"type": "keyword"
},
"sponsorshipSets": {
"type": "nested",
"properties": {
"id": {
"type": "keyword"
},
"sponsorships": {
"type": "nested",
"properties": {
"id": {
"type": "keyword"
}
}
}
}
}
}
You can use exists query to filter such documents. Below query should help.
Query Request:
POST <your_index_name>/_search
{
"query":{
"bool":{
"must":{
"nested":{
"path":"sponsorshipSets",
"query":{
"nested":{
"path":"sponsorshipSets.sponsorships",
"query":{
"bool":{
"must_not":[
{
"exists":{
"field":"sponsorshipSets.sponsorships"
}
}
]
}
}
}
}
}
},
"filter":[
{
"term":{
"brandId":"b1d28821-3730-4266-8f55-eb69596004fb"
}
}
]
}
}
}
This should return all three scenarios where your document JSON structure would be
sponsorshipSets.sponsorships: {} i.e. you have empty structure for sponsorships
sponsorshipSets.sponsorships: null i.e. the value is set as null
Or your document doesn't have sponsorships field in first place.
You don't need to use any aggregations for this as ES would return you the count of such documents in hits.total.value of the response.
Let me know if this helps!
Is it possible using the Elastic Search _count API and having the following abbreviated ES template to find the count of sponsorships for all the campaigns by brandId?
sponsorshipSets and sponsorships are optional so it can be null.
{
"index_patterns": "campaigns*",
"order": 4,
"version": 4,
"aliases": {
"campaigns": {
}
},
"settings": {
"number_of_shards": 5
},
"mappings": {
"dynamic": "false",
"properties": {
"brandId": {
"type": "keyword"
},
"sponsorshipSets": {
"type": "nested",
"properties": {
"id": {
"type": "keyword"
},
"sponsorships": {
"type": "nested",
"properties": {
"id": {
"type": "keyword"
}
}
}
}
}
}
filter aggregation can be used to fetch docs with certain brand Id. Two Nested aggregations to point to sponsorship and value_count aggregation to get the count.
Query
{
"aggs": {
"selected_brand": {
"filter": {
"term": {
"brandId": "1"
}
}
},
"sponsorshipSets": {
"nested": {
"path": "sponsorshipSets"
},
"aggs": {
"sponsorships": {
"nested": {
"path": "sponsorshipSets.sponsorships"
},
"aggs": {
"count": {
"value_count": {
"field": "sponsorshipSets.sponsorships.id"
}
}
}
}
}
}
}
}
I found a solution without using Aggregations, it seems more accurate from the above and I can use the _count API.
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "sponsorshipSets.sponsorships",
"query": {
"bool": {
"filter": {
"exists": {
"field": "sponsorshipSets.sponsorships"
}
}
}
}
}
},
{
"term": {
"brandId": "b1d28821-3730-4266-8f55-eb69596004fb"
}
}
]
}
}
}
I'm try to extract aggregated data, but I'm a little lost when I want to further filter a set of documents. Getting the color seems ok, but when I want to aggregate the categories with some colors filter the query fail. What am I doing wrong on this query?
This is the query I already have:
GET/my_index/_search
{
"_source": false,
"aggs": {
"global": {
"global": {
},
"aggs": {
"all_products": {
"nested": {
"path": "simple"
},
"aggs": {
"filter_top": {
"filter": {
"bool": {
"must": [
{
"match": {
"simple.compound_words": {
"query": "tisch",
"operator": "AND"
}
}
}
]
}
},
"aggs": {
"filter_merged": {
"aggs": {
"filter": {
"bool": {
"must": [
{
"terms": {
"simple.filter_color": [
"green",
"red"
]
}
}
]
}
},
"aggs": {
"filter_category": {
"terms": {
"field": "simple.filter_category"
}
}
}
}
},
"filter_color": {
"terms": {
"field": "simple.filter_color"
}
}
}
}
}
}
}
}
}
}
This is the relevant part of the index mappings.
{
"my_index": {
"mappings": {
"_doc": {
"properties": {
"simple": {
"type": "nested",
"properties": {
"compound_words": {
"type": "text",
"analyzer": "GermanCompoundWordsAnalyzer"
},
"filter_category": {
"type": "keyword"
},
"filter_color": {
"type": "keyword"
}
}
}
}
}
}
}
}
Thanks for your support.
I have an document with the following mappings:
{
"some_doc_name": {
"mappings": {
"_doc": {
"properties": {
"stages": {
"properties": {
"name": {
"type": "text"
},
"durationMillis": {
"type": "long"
}
}
}
}
}
}
}
}
And I would like to have an aggregation like: "The average duration of the stages which name contains the SCM token"
I tried something like:
{
"aggs": {
"scm_stage": {
"filter": {
"bool": {
"should": [{
"match_phrase": {
"stages.name": "SCM"
}
}]
}
},
"aggs" : {
"avg_duration": {
"avg": {
"field": "stages.durationMillis"
}
}
}
}
}
}
But that's giving me the average of all stages for all documents that contain at least one stage with the SCM token. Any advice on how to get this aggregation right?
Answering my own question thanks to the help of val
My mappings file was missing the "type": "nested", something like:
...
"stages": {
"type": "nested",
"properties": {
"id": {
"type": "keyword",
"ignore_above": 256
},
...
Then I can get my aggregation working with something like this:
{
"size": 0,
"query": {
"nested": {
"path": "stages",
"query": {
"match": {
"stages.name": "scm"
}
}
}
},
"aggs": {
"stages": {
"nested": {
"path": "stages"
},
"aggs": {
"stages-filter": {
"filter": {
"terms": {
"stages.name": [
"scm"
]
}
},
"aggs": {
"avg_duration": {
"avg": {
"field": "stages.durationMillis"
}
}
}
}
}
}
}
}
I have a nested type mapping in my index:
"actors": {
"type": "nested",
"properties": {
"actor": {
"type": "nested",
"properties": {
"actor_full_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
When i see the datas it looks to be ok
The request
GET /test_index/film/_search
{
"size": 100,
"_source": "actors.actor.actor_full_name"
}
Give me this answer:
"actors": {
"actor": [
{
"actor_full_name": "Antonio BANDERAS"
},
{
"actor_full_name": "Diane VENORA"
},
{
"actor_full_name": "Omar SHARIF"
},
{
"actor_full_name": "Vladimir KULICH"
}
]
},
...
I am trying to do a nested aggregation request on actor_full_name field
I am trying this request:
POST /test_index/film/_search
{
"size": 0,
"aggs": {
"actor_nested_agg_code": {
"nested": {
"path": "actors"
},
"aggs": {
"code_actor_agg": {
"terms": {
"field": "actor.actor_full_name.keyword",
"size": 100
}
}
}
}
}
}
Unfortunately it appears to give me an incorect aswere :
"aggregations": {
"actor_nested_agg_code": {
"doc_count": 1807,
"code_actor_agg": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
}
Do you see what i did wrong and how i could fix it please?
You either didn't mean to make actors nested as well, or you overlooked that you have two nested fields in there:
{
"size": 0,
"aggs": {
"actor_nested_agg_code": {
"nested": {
"path": "actors"
},
"aggs": {
"second_nested_actor": {
"nested": {
"path": "actors.actor"
},
"aggs": {
"code_actor_agg": {
"terms": {
"field": "actors.actor.actor_full_name.keyword",
"size": 100
}
}
}
}
}
}
}
}