Dioralop
Dioralop

Reputation: 165

Elasticsearch - Sorting by a nested field in 2019

So I'm trying to figure out a way of sorting documents based on a single property of its nested documents. So for example, let's say I have a 'videos' index. Each video has a list of categories that the video belongs to. Each category is a nested document which contains certain metadata about the category e.g. id, views, slug. Here's an example mapping:

 "videos" : {
    "properties" : {
      "categories" : {
        "type" : "nested",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "views" : {
            "type" : "integer"
          },
          "slug" : {
            "type" : "keyword"
          }
        }
      },
      "title" : {
        "type" : "text"
      },
    }
  }

And here's an example document:

  {
    "_index" : "videos",
    "_id" : "123",
    "_source" : {
      "title" : "this is a test video",
      "categories" : [
        {
          "id" : 3533,
          "slug" : "animals",
          "views" : 314
        },
        {
          "id" : 3564,
          "slug" : "comedy",
          "views" : 814
        },
        {
          "id" : 4072,
          "slug" : "politics",
          "views" : 80
        }
      ],
    }
  }

So I would want to sort videos by the views on a certain category. For example sort videos by views on the 'comedy' category in descending order. I've scoured the web for a solution to this but most of them seem to be very specific to one problem or use outdated queries.

Upvotes: 2

Views: 724

Answers (1)

jaspreet chahal
jaspreet chahal

Reputation: 9099

Ypu need to use nested filter. You can get further info https://qbox.io/blog/sorting-nested-fields-in-elasticsearch

GET videos/_search
{

  "sort": [
    {
      "categories.views": {
        "order": "asc",
        "nested": {
          "path": "categories",
          "filter": {
            "term": {
              "categories.slug": "comedy"
            }
          }
        }
      }
    }
  ]
}

Result

   "hits" : [
      {
        "_index" : "videos",
        "_type" : "_doc",
        "_id" : "uT6bRGsBFW2mvGhmMxUU",
        "_score" : null,
        "_source" : {
          "title" : "this is a test video",
          "categories" : [
            {
              "id" : 3533,
              "slug" : "animals",
              "views" : 314
            },
            {
              "id" : 3564,
              "slug" : "comedy",
              "views" : 814
            },
            {
              "id" : 4072,
              "slug" : "politics",
              "views" : 80
            }
          ]
        },
        "sort" : [
          814
        ]
      },
      {
        "_index" : "videos",
        "_type" : "_doc",
        "_id" : "uj6bRGsBFW2mvGhmXxWl",
        "_score" : null,
        "_source" : {
          "title" : "this is a test video",
          "categories" : [
            {
              "id" : 3533,
              "slug" : "animals",
              "views" : 314
            },
            {
              "id" : 3564,
              "slug" : "comedy",
              "views" : 900
            },
            {
              "id" : 4072,
              "slug" : "politics",
              "views" : 80
            }
          ]
        },
        "sort" : [
          900
        ]
      }
    ]

Upvotes: 3

Related Questions