# Sorting and Filtering

### Sorting and Filtering

The default sort order is relevancy and it is always recommended unless the use case is very specific or if the user has specifically requested to order the results in a specific order.

Filtering is similar to faceting, it includes only products that match criteria set by the filter. Whereas facets are intended for filtering for end users, filters as presented here are intended for implementation level filtering. For example you may choose not to include products out of stock by using a filter.

## When can Sorting and Filtering be Applied

Sorting and filtering can be applied on the following calls:

* Search
* Category listings
* Related products

The examples on this page show how to add facets to a `getEntitiesByAttribute` call. The same logic can be applied to `search` by replacing the `getEntitiesByAttribute` call with `search` call and for Java and C# create the `request` object as an instance of `SearchRequest` instead of `GetEntitiesByAttributeRequest`.

## Sorting

The sort order is defined by supplying a list of hierarchical attributes along with the `Order` parameter to specify ascending or descending sort order. The first item in the list specifies the primary sort order, the second specifies the secondary sort order etc.

{% tabs %}
{% tab title="C#" %}
```
// Category listing with sorting
var request = new GetEntitiesByAttributeRequest("Category", categoryName);

//Set the sort order of the products in the category
request.ResultsOptions.SortBy = new List<EntitySortingParameter>{
    new EntitySortingParameter("Price")
        { Order = SortOrders.Asc}, // Primary sorting: Sort on attribute Price, ascending order
    new EntitySortingParameter(EntitySortingParameter.Types.Popularity)
        { Order = SortOrders.Desc} // Secondary sorting: Sort on popularity, descending order
};

var response = _loop54Client.GetEntitiesByAttribute(request);
```

C# source code on Github: [CategoryListingController.cs](https://github.com/LoopFiftyFour/.NET-Connector/blob/master/Loop54.NetCoreCodeExamples/Controllers/CategoryListingController.cs)
{% endtab %}

{% tab title="Java" %}
```
// Category listing with sorting
GetEntitiesByAttributeRequest request = new GetEntitiesByAttributeRequest("Category", categoryName);

//Set the sort order of the products in the category
request.resultsOptions.sortBy = new ArrayList<>();
request.resultsOptions.sortBy.add(new EntitySortingParameter("Price"){{ order = SortOrders.ASC; }}); // Primary sorting: Sort on attribute Price, ascending order
request.resultsOptions.sortBy.add(new EntitySortingParameter(EntitySortingParameter.Types.POPULARITY){{ order = SortOrders.DESC; }});// Secondary sorting: Sort on popularity, descending order

GetEntitiesByAttributeResponse response = loop54Client.getEntitiesByAttribute(request);
```

Java source code on Github: [CategoryListingController.java](http://categorylistingcontroller.java)
{% endtab %}

{% tab title="JavaScript" %}
```
// Category listing with sorting
// Set the sort order of the products in the category
var options = {
sortBy: [{type:"attribute", attributeName:"Price", order:"asc"}, // Primary sorting: Sort on attribute Price, ascending order
            {type:"popularity", order:"desc"}] // Secondary sorting: Sort on popularity, descending order. Secondary sorting is used when items are equal in the primary sorting.
};

var response = client.getEntitiesByAttribute("Category", categoryName, options);
```

JavaScript source code on Github: [categorylisting.js](https://github.com/LoopFiftyFour/JS-Connector/blob/master/codeexamples/categorylisting.js)
{% endtab %}

{% tab title="PHP" %}
```
/* Sort by ascending values in the "Price" attribute */
$request->resultsOptions()->sortBy(
\Loop54\API\ResultsOptions::TYPE_ATTRIBUTE,
\Loop54\API\ResultsOptions::ORDER_ASC,
'Price'
);

/* Sorting on multiple criteria is possible, but uses a clunky interface */
$request->resultsOptions()->getRaw()->setSortBy([
new \Loop54\API\OpenAPI\Model\EntitySortingParameter([
    'type' => \Loop54\API\ResultsOptions::TYPE_ATTRIBUTE,
    'order' => \Loop54\API\ResultsOptions::ORDER_DESC,
    'attribute_name' => 'Price'
]),
new \Loop54\API\OpenAPI\Model\EntitySortingParameter([
    'type' => \Loop54\API\ResultsOptions::TYPE_POPULARITY,
    'order' => \Loop54\API\ResultsOptions::ORDER_DESC
])
]);
```

PHP source code on Github: [Simple.php](https://github.com/LoopFiftyFour/PHP-Connector/blob/master/examples/Simple.php)
{% endtab %}
{% endtabs %}

### Filters

Filter results based on attribute values by supplying the attribute and the value that you want to filter on.

{% tabs %}
{% tab title="C#" %}
```
// Category listing with filters
var request = new GetEntitiesByAttributeRequest("Category", categoryName);

//Filter the products in the category
//In this case, we only want products that have got
//the price attribute, and where the organic attribute is set to "True"
request.ResultsOptions.Filter = new AndFilterParameter(
    new AttributeExistsFilterParameter("Price"),
    //Because the organic attribute is stored as a string in the engine we need to filter with that type.
    //If it would have been stored as a boolean we would have used bool instead.
    new AttributeFilterParameter<string>("Organic", "True")
);

var response = _loop54Client.GetEntitiesByAttribute(request);
```

C# source code on Github: [CategoryListingController.cs](https://github.com/LoopFiftyFour/.NET-Connector/blob/master/Loop54.NetCoreCodeExamples/Controllers/CategoryListingController.cs)
{% endtab %}

{% tab title="Java" %}
```
// Category listing with filters
GetEntitiesByAttributeRequest request = new GetEntitiesByAttributeRequest("Category", categoryName);

// Filter the products in the category
// In this case, we only want products that have got
// the price attribute, and where the organic attribute is set to "True"
request.resultsOptions.filter = new AndFilterParameter(
new AttributeExistsFilterParameter("Price"),
//Because the organic attribute is stored as a string in the engine we need to filter with that type.
//If it would have been stored as a boolean we would have used bool instead.
new AttributeFilterParameter<String>("Organic", "True")
);

GetEntitiesByAttributeResponse response = loop54Client.getEntitiesByAttribute(request);
```

Java source code on Github: [CategoryListingController.java](https://github.com/LoopFiftyFour/Java-Connector/blob/master/codeexamples/src/main/java/com/loop54/spring/test/codeexamples/web/CategoryListingController.java)
{% endtab %}

{% tab title="JavaScript" %}
```
// Category listing with filters
// Filter the products in the category
// In this case, we only want products that have got
// the price attribute, and where the organic attribute is set to "True"
var response = client.getEntitiesByAttribute(
"Category",
categoryName,
{
    filter: {
        and:[
            { attributeName:"Price" }, // The price attribute must exist
            { type:"attribute", attributeName:"Organic", value:"True" } // AND the Organic attribute must be set to "True"
        ]
    }
}
);
```

JavaScript source code on Github: [categorylisting.js](https://github.com/LoopFiftyFour/JS-Connector/blob/master/codeexamples/categorylisting.js)
{% endtab %}

{% tab title="PHP" %}
```
$filters = new \Loop54\API\FilterParameter();

$request = $connector->getEntitiesByAttribute(
'Manufacturer',
'Sweet Home Alabama'
);
/* Filter results to only see new items with a price */
$request->resultsOptions()->filter(
$filters->attributeExists('Price')
->and($filters->attribute('IsNew', true))
);
```

PHP source code on Github: [Simple.php](https://github.com/LoopFiftyFour/PHP-Connector/blob/master/examples/Simple.php)
{% endtab %}
{% endtabs %}
