Sort Index Query Results
-
This article provides examples of sorting query results when querying a static-index.
-
Prior to this article, please refer to Sort dynamic queries results for dynamic-queries examples
and general knowledge about Sorting. -
All sorting capabilities provided for a dynamic query can also be used when querying a static-index.
-
In this page:
Order by index-field value
Use orderByDescending
to order the results by the specified index-field.
/** @var array<Product> $products */
$products = $session
// Query the index
->query(Products_ByUnitsInStock_IndexEntry::class, Products_ByUnitsInStock::class)
// Apply filtering (optional)
->whereGreaterThan("UnitsInStock", 10)
// Call 'OrderByDescending', pass the index-field by which to order the results
->orderByDescending("UnitsInStock")
->ofType(Product::class)
->toList();
// Results will be sorted by the 'UnitsInStock' value in descending order,
// with higher values listed first.
/** @var array<Product> $products */
$products = $session->advanced()
// Query the index
->documentQuery(Products_ByUnitsInStock_IndexEntry::class, Products_ByUnitsInStock::class)
// Apply filtering (optional)
->whereGreaterThan("UnitsInStock", 10)
// Call 'OrderByDescending', pass the index-field by which to order the results
->orderByDescending("UnitsInStock")
->ofType(Product::class)
->toList();
// Results will be sorted by the 'UnitsInStock' value in descending order,
// with higher values listed first.
class Products_ByUnitsInStock_IndexEntry
{
private ?int $unitsInStock = null;
public function getUnitsInStock(): ?int
{
return $this->unitsInStock;
}
public function setUnitsInStock(?int $unitsInStock): void
{
$this->unitsInStock = $unitsInStock;
}
}
class Products_ByUnitsInStock extends AbstractIndexCreationTask
{
public function __construct()
{
parent::__construct();
$this->map = "docs.Products.Select(product => new {" .
" UnitsInStock = product.UnitsInStock" .
"})";
}
}
from index "Products/ByUnitsInStock"
where UnitsInStock > 10
order by UnitsInStock as long desc
Ordering Type:
-
By default,
orderByDescending
will determine theOrderingType
from the property path expression
and specify that ordering type in the generated RQL that is sent to the server. -
E.g., in the above example, ordering by
UnitsInStock
will result inOrderingType::int
because that property data type is an integer. -
Different ordering can be forced.
See section Force ordering type for all available ordering types.
The same syntax used with dynamic queries also applies to queries made on indexes.
Order results when index-field is searchable
-
When configuring an index-field for full-text search, the content of the index-field is broken down into terms at indexing time. The specific tokenization depends on the analyzer used.
-
When querying such index, if you order by that searchable index-field, results will come back sorted based on the terms, and not based on the original text of the field.
-
To overcome this, you can define another index-field that is not searchable and sort by it.
class Products_BySearchName_IndexEntry
{
// Index-field 'Name' will be configured below for full-text search
private ?string $name = null;
// Index-field 'NameForSorting' will be used for ordering query results
private ?string $nameForSorting = null;
public function getName(): ?string
{
return $this->name;
}
public function setName(?string $name): void
{
$this->name = $name;
}
public function getNameForSorting(): ?string
{
return $this->nameForSorting;
}
public function setNameForSorting(?string $nameForSorting): void
{
$this->nameForSorting = $nameForSorting;
}
}
class Products_BySearchName extends AbstractIndexCreationTask
{
public function __construct()
{
parent::__construct();
$this->map = "docs.Products.Select(product => new {" .
" Name = product.Name," .
" NameForSorting = product.Name" .
"})";
$this->index("Name", FieldIndexing::search());
}
}
/** @var array<Product> $products */
$products = $session
// Query the index
->query(Products_BySearchName_IndexEntry::class, Products_BySearchName::class)
// Call 'Search':
// Pass the index-field that was configured for FTS and the term to search for.
// Here we search for terms that start with "ch" within index-field 'Name'.
->search("Name", "ch*")
// Call 'OrderBy':
// Pass the other index-field by which to order the results.
->orderBy("NameForSorting")
->ofType(Product::class)
->toList();
// Running the above query on the NorthWind sample data, ordering by 'NameForSorting' field,
// we get the following order:
// =========================================================================================
// "Chai"
// "Chang"
// "Chartreuse verte"
// "Chef Anton's Cajun Seasoning"
// "Chef Anton's Gumbo Mix"
// "Chocolade"
// "Jack's New England Clam Chowder"
// "Pâté chinois"
// "Teatime Chocolate Biscuits"
// While ordering by the searchable 'Name' field would have produced the following order:
// ======================================================================================
// "Chai"
// "Chang"
// "Chartreuse verte"
// "Chef Anton's Cajun Seasoning"
// "Pâté chinois"
// "Chocolade"
// "Teatime Chocolate Biscuits"
// "Chef Anton's Gumbo Mix"
// "Jack's New England Clam Chowder"
/** @var array<Product> $products */
$products = $session->advanced()
// Query the index
->documentQuery(Products_BySearchName_IndexEntry::class, Products_BySearchName::class)
// Call 'Search':
// Pass the index-field that was configured for FTS and the term to search for.
// Here we search for terms that start with "ch" within index-field 'Name'.
->search("Name", "ch*")
// Call 'OrderBy':
// Pass the other index-field by which to order the results.
->orderBy("NameForSorting")
->ofType(Product::class)
->toList();
from index "Products/BySearchName"
where search(Name, "ch*")
order by NameForSorting
Additional sorting options
-
When querying an index, the following sorting options are the same as when making a dynamic query.
-
Refer to the examples in the links below to see how each option is achieved.