0
votes

i am doing aggregations on "location" field in my document ,where there is also a "city" field in the same document.I am querying the document on city field and aggregating the documents on location field.

{
  "aggs": {
    "locations": {
      "terms": {
        "field": "location",
        "min_doc_count": 0
      }
    }
  },
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "city": "mumbai",
                "_cache": true
              }
            }
          ]
        }
      }
    }
  }
}

Now the count and aggregations come fine and along with the hits.but my problem is that i want to do aggregation with 'doc-count' set to 0 and the aggregation bucket returns me all the lcoations with 0 count which even falls in other city.I want to get 0 count locations only for that city.want to scope the context of 0 count location to city. I tried achieving this by nested aggregation placing location inside nested city and then doing aggs, or combining the filter aggs with terms agg but still getting the same result.Is there any way to achieve this or elasticsearch is inherently build to work like this. ES Version - 1.6

My mapping looks like this:

{
  "service": {
    "_source": {
      "enabled": true
    },
    "properties": {
      "name": {
        "type": "string",
        "index": "not_analyzed"
      },
      "location": {
        "type": "string",
        "index": "not_analyzed"
      },
      "city": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}

Sample docs to index

{ "name": "a", "location": "x", "city": "mumbai" }

{ "name": "b", "location": "x", "city": "mumbai" }

{ "name": "c", "location": "y" "city": "chennai" }

1
yeah, just read the note on ES documentation for this, ES is build to work like this.Is there anybody out able to hack this trick... - user3775217
Please show your current query and eventually the mapping you're using as well. - Val
mappings: "service" :{ "_source" : {"enabled" : true }, "properties":{ "name" : {"type" : "string", "index" : "not_analyzed"}, "location" : {"type" : "string", "index" : "not_analyzed"}, "city" : {"type" : "string", "index" : "not_analyzed"} - user3775217
Query : { "aggs": { "locations": { "terms": { "field": "location", "min_doc_count": 0, } } }, "query": { "filtered": { "filter": { "bool": { "must": [ { "term": { "city": "mumbai", "_cache": true } } ] } } } } } @Val - user3775217

1 Answers

1
votes

You should try to sort your terms aggregation (embedded into a filter aggregation) by ascending doc count and you'll get all the terms with 0 doc count first. Note that by default, you'll only get the first 10 terms, if you have less terms with 0 doc count, you'll see them all, otherwise you might need to increase the size parameter to something higher than 10.

{
  "aggs": {
    "city_filter": {
      "filter": {
        "term": {
          "city": "mumbai"
        }
      },
      "aggs": {
        "locations": {
          "terms": {
            "field": "location",
            "min_doc_count": 0,
            "size": 20,         <----- add this if you have more than ten 0-doc-count terms
            "order": {          <----- add this to see 0-doc-count first
              "_count": "asc"
            }
          }
        }
      }
    }
  },
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "city": "mumbai",
                "_cache": true
              }
            }
          ]
        }
      }
    }
  }
}