0
votes

I'm unable to limit the results of a nested aggregation query using match_phrase_prefix in Elasticsearch v6.8.0

I am able to limit results of a non-nested aggregation using the match_phrase_prefix. I expected to be able to apply the same logic to a nested field, as shown below. The index mapping properly lists the nested field type as nested, and I'm able to aggregate the field without any filters successfully (using match_all).

Successful non-nested field aggregation with match_phrase_prefix query:

GET index/_search
{
  "query":{
    "match_phrase_prefix": {
      "field1": "Nurse"
    }
  },
  "size":0,
  "aggs":{
    "field1":{
      "terms":{
        "field":"field1",
        "size":100,
        "order":{
          "_count": "desc"
        }
      }
    }
  }
}

Successful nested field aggregation (without match_phrase_prefix):

GET index/_search
{
  "query":{
    "match_all": {}
  },
  "size":0,
  "aggs":{
    "field2":{
      "nested":{
        "path":"field2"
      },
      "aggs":{
        "field2.nestedField":{
           "terms":{
              "field":"field2.nestedField",
              "size":100,
              "order":{
                "_count": "desc"
              }
            }
          }
        }
      }
    }
  }

Unsuccessful nested field aggregation with match_phrase_prefix:

GET index/_search
{
  "query":{
    "match_phrase_prefix": {
      "field2.nestedField": "en"
    }
  },
  "size":0,
  "aggs":{
    "field2":{
      "nested":{
        "path":"field2"
      },
      "aggs":{
        "field2.nestedField":{
           "terms":{
              "field":"field2.nestedField",
              "size":100,
              "order":{
                "_count": "desc"
              }
            }
          }
        }
      }
    }
  }

The expected output of the third query is a list of buckets with keys matching the prefix filter. Instead, I'm seeing an empty result list. Is there a way to structure match_phrase_prefix to work with nested fields? Or a way to apply a filter at the term level?

2

2 Answers

0
votes

You need to use a nested query for this (documentation here)

this query

"query":{ "match_phrase_prefix": { "field2.nestedField": "en" } }

return nothing because your index documents do not contain the nestedField field. This field belongs to nested documents.

The correct query is :

GET index/_search
{
  "query": {
    "nested": {
      "path": "field2",
      "query": {
        "match_phrase_prefix": {
          "field2.nestedField": "en"
        }
      }
    }
  },
  "size": 0,
  "aggs": {
    "field2": {
      "nested": {
        "path": "field2"
      },
      "aggs": {
        "field2.nestedField": {
          "terms": {
            "field": "field2.nestedField",
            "size": 100,
            "order": {
              "_count": "desc"
            }
          }
        }
      }
    }
  }
}
0
votes

Solved this issue with the use of a nested top-level query. See this question for the working solution (using terms instead of a prefix filter):

Elasticsearch - How to filter nested aggregation bucket?

Example:

GET index/_search
{  
  "query":{  
    "nested":{  
      "path":"field2",
      "query":{  
        "match_phrase_prefix":{  
          "field2.nestedField":"en"
        }
      }
    }
  },
  "size":0,
  "aggs":{  
    "field2":{  
      "nested":{  
        "path":"field2"
      },
      "aggs":{  
        "innerFilter":{  
          "filter":{  
            "prefix":{  
              "field2.nestedField":"en"
            }
          },
          "aggs":{  
            "field2.nestedField":{  
              "terms":{  
                "field":"field2.nestedField",
                "size":100,
                "order":{  
                  "_count":"desc"
                }
              }
            }
          }
        }
      }
    }
  }
}