# Sort results based on the number of matched nested documents

**URL:** https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525
**Category:** Elasticsearch
**Created:** [November 1, 2016, 8:09am UTC](https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525 "2016-11-01T08:09:09Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Dzmitry\_Kavalionak](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dzmitry_kavalionak/32/12862_2.png) [@Dzmitry\_Kavalionak](https://discuss.elastic.co/u/Dzmitry_Kavalionak)
#### Post date: [November 1, 2016, 8:09am UTC](https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525/1 "2016-11-01T08:09:09Z")

</div>

I have the following index

```
PUT /index/blogpost/2
{
  "title": "Investment secrets",
  "body": "What they don't tell you ...",
  "tags": ["shares", "equities"],
  "comments": [
    {
      "name": "Mary Brown",
      "comment": "Lies, lies, lies",
      "age": 42,
      "stars": 1,
      "date": "2014-10-18"
    },
    {
      "name": "John Smith",
      "comment": "You're making it up!",
      "age": 28,
      "stars": 2,
      "date": "2014-10-16"
    }
  ]
}

```

Is it possible to sort posts based on the count of comments in October like this

```
GET /_search
{
  "query": {
    "nested": { 
      "path": "comments",
      "filter": {
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt": "2014-11-01"
          }
        }
      }
    }
  },
  "sort": {
    "comments": { 
      "order": "desc",   
      "mode": "doc_count",   
      "nested_filter": { 
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt": "2014-11-01"
          }
        }
      }
    }
  }
}

```

I know that there is no "doc\_count" sort mode in elasticsearch and the query above is invalid.

Is there a way to sort posts by the number of comments in October?

---

<div class="post-metadata">

### Author: ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)
#### Post date: [November 1, 2016, 8:54am UTC](https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525/2 "2016-11-01T08:54:11Z")

</div>

Hi,

have you tried script sort? Something along these lines might work:

```auto
"sort": {
    "_script": {
      "script": "doc['comments'].values.length",
      "order": "desc",
      "type": "string"
    }
  }

```

I haven't tried it myself because I don't have your data but it might be a starting point. On the other hand I'm not sure it it does the range filtering on the nested docs or would just score by total count of comments, regardless or range... Need to do some digging here.

---

<div class="post-metadata">

### Author: ![Dzmitry\_Kavalionak](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dzmitry_kavalionak/32/12862_2.png) [@Dzmitry\_Kavalionak](https://discuss.elastic.co/u/Dzmitry_Kavalionak)
#### Post date: [November 7, 2016, 7:07pm UTC](https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525/3 "2016-11-07T19:07:29Z")

</div>

@cbuescher thank you very much for the help! When I try this query

```
curl -XGET localhost:9200/posts/_search -d '
{
  "query": {
    "nested": { 
      "path": "comments",
      "filter": {
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt": "2014-11-01"
          }
        }
      }
    }
  },
  "sort": {
    "_script": {
      "script": "doc[\"comments\"].values.length",
      "order": "desc",
      "type": "string"
    }
  }
}' 

```

I get the following error:

```
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 3,
    "failed" : 2,
    "failures" : [ {
      "shard" : 2,
      "index" : "posts",
      "node" : "hOLwx1QZQX-r-_2lyLBACQ",
      "reason" : {
        "type" : "script_exception",
        "reason" : "failed to run inline script [doc[\"comments\"].values.length] using lang [groovy]",
        "caused_by" : {
          "type" : "illegal_argument_exception",
          "reason" : "No field found for [comments] in mapping with types []"
        }
      }
    } ]
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : []
  }
}

```

I googled this error and could not find the solution. Do you have any ideas?

I have the following mappings:

```
curl -XPOST localhost:9200/posts -d '
{
  "mappings": {
    "post": {
      "properties": {
        "title": { "type": "string" },
        "body": { "type": "string" },
        "tags": { "type": "string" },
        "comments": {
          "type": "nested",
          "properties": {
            "name": { "type": "string" },
            "comment": { "type": "string" },
            "age": { "type": "integer" },
            "stars": { "type": "integer" },
            "date": { "type": "date" }
          }
        }
      }
    }
  }
}'
```

---

<div class="post-metadata">

### Author: ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)
#### Post date: [November 11, 2016, 3:07pm UTC](https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525/4 "2016-11-11T15:07:53Z")

</div>

Hi,

Sorry for the late reply, it took me some time to wrap my head around this as well. My initial idea with the script sort was misleading because, as you saw, acessing nested fields from the parent document context in scripts is not possible. The simplest solution in your case would be to (ab)use the `score_mode` of the nested query, which lets you control how matching nested docs affect the score of the parent. Since your range query is already in a filter, all matching nested docs have score `1` and by setting `score_mode` to `sum` you can get the count of all matching documents.

Also, if you only want to retrieve only the matching nested documents for your range, you can also use the nested `inner_hits` part. That way, the "inner\_hits" section for each parent document should only contain the comments matching your range:

```auto
GET /posts/_search
{
  "query": {
    "nested": { 
      "path": "comments",
      "filter": {
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt": "2014-11-01"
          }
        }
      },
      "score_mode": "sum",
      "inner_hits" : {}
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [July 5, 2017, 10:05pm UTC](https://discuss.elastic.co/t/sort-results-based-on-the-number-of-matched-nested-documents/64525/5 "2017-07-05T22:05:53Z")

</div>


