Sorting

Problem Description

Our current rentals search results page has the capability to sort a set of returned listings by the fields price, number of beds and baths using a SQL 'orderby' with multiple columns.

I tried to duplicate this functionality using the 'sortBy' criteria sorting by price.

What I found was that the listings returned by the Discovery Engine only sort by the 'sortBy' criteria and ignores the relevance of the listing search.

So searching just by listing type of Rentals, I get listings ordered by price which is fine...

{
  "_discovery": {
    "request": {
      "criteria": [
        {
          "dimension": "list_type",
          "value": "Rentals"
        }
      ],
      "pageSize": 10,
      "sortBy": [
        {
          "dimension": "price",
          "reverse": true
        }
      ],
      "startIndex": 0
    },
    "response": {
      "availableSize": 1500,
      "currentPageSize": 10,
      "datasetSize": 1502,
      "exactMatches": [true, true, true, true, true, true, true, true, true, true],
      "exactSize": 1500,
      "itemIds": ["411165986", "234154538", "404083486", "408485835", "423539513", "404085315", "408268240", "436356728", "381385364", "374093834"],
      "pageSize": 10,
      "relevanceValues": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
      "startIndex": 0,
      "totalSize": 1500
    }
  },
  "results_query_params": "totalSize=1500&exactSize=1500&startIndex=0&pageSize=10&itemIds=411165986,234154538,404083486,408485835,423539513,404085315,408268240,436356728,381385364,374093834&exactMatches=true,true,true,true,true,true,true,true,true,true"
}

When I add a search criteria of 1 bedroom, I get 158 exact matches, but
the first page of results is ordered by price and ignores the relevance
of the 1 bedroom search.

{

"_discovery": {
  "request": {
    "criteria": [
      {
        "dimension": "list_type",
        "value": "Rentals"
      },
      {
        "dimension": "bedroom",
        "value": 1
      }
    ],
    "pageSize": 10,
    "sortBy": [
      {
        "dimension": "price",
        "reverse": true
      }
    ],
    "startIndex": 0
  },
  "response": {
    "availableSize": 1323,
    "currentPageSize": 10,
    "datasetSize": 1502,
    "exactMatches": [false, false, false, false, false, false, false, false, false, false],
    "exactSize": 158,
    "itemIds": ["234154538", "408485835", "408268240", "381385364", "374093834", "434992100", "348199991", "437247740", "424401004", "426503032"],
    "pageSize": 10,
    "relevanceValues": [0.99999999883584678, 0.99999999976716936, 0.99999999953433871, 0.99999999953433871, 0.99999999883584678, 0.99999999953433871, 0.99999999883584678, 0.99999999906867743, 0.99999999976716936, 0.99999999930150807],
    "startIndex": 0,
    "totalSize": 1323
  }
},
"results_query_params": "totalSize=1323&exactSize=158&startIndex=0&pageSize=10&itemIds=234154538,408485835,408268240,381385364,374093834,434992100,348199991,437247740,424401004,426503032&exactMatches=false,false,false,false,false,false,false,false,false,false"

}

--

Is there a way to sort results by a dimension like price while searching with a different criteria like number of bedrooms while maintaining the relevance of exact matches for the bedroom criteria?


Answer

There are two different approaches that you could take here.

  1. Use weights overrides to affect the score of the each search result.
  2. Use sortBy to affect the final sorting of the result set.

I'll skip the first approach for now as you are directly asking about the second.

The key to fixing this is to understand what the engine's default sortBy criterion are. If you do not specify an override they get set to:

{
  "sortBy": [
    {
      "builtin": "exactMatch"
    },
    {
      "builtin": "relevance"
    },
    {
      "builtin": "id"
    }
  ]
}

When you set your own custom sortBy the defaults get added to the end if they are not already specified. Thus your sample sortBy criterion of

{
  "sortBy": [
    {
      "dimension": "price",
      "reverse": true
    }
  ]
}

Gets turned into this:

{
  "sortBy": [
    {
      "dimension": "price",
      "reverse": true
    },
    {
      "builtin": "exactMatch"
    },
    {
      "builtin": "relevance"
    },
    {
      "builtin": "id"
    }
  ]
}

If you move the price criterion below the exactMatch criterion then the exactMatches will appear first in the resultset and both exact and close matches will be ordered by price, relevance, id.

{
  "sortBy": [
    {
      "builtin": "exactMatch"
    },
    {
      "dimension": "price",
      "reverse": true
    },
    {
      "builtin": "relevance"
    },
    {
      "builtin": "id"
    }
  ]
}