PHPackages                             mongerinc/search-request - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. mongerinc/search-request

ActiveLibrary[Search &amp; Filtering](/categories/search)

mongerinc/search-request
========================

Represent complex search queries and convert them to and from JSON

v6.0.0(7y ago)252.1kMITPHPPHP &gt;=5.4.0

Since Dec 15Pushed 7y ago4 watchersCompare

[ Source](https://github.com/mongerinc/search-request)[ Packagist](https://packagist.org/packages/mongerinc/search-request)[ Docs](https://github.com/mongerinc/search-request)[ RSS](/packages/mongerinc-search-request/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (10)Dependencies (1)Versions (27)Used By (0)

SearchRequest
-------------

[](#searchrequest)

This library provides a set of classes that help represent requests for complex data and provides a way to convert requests to and from a standard JSON format. If you have interfaces with tons of parameters ($filters, $groupings, $page, $rowsPerPage, etc.), or if you're just looking for a standard way to communicate complex requests to other apps without racking your brain over how to represent this data in JSON, you will like this library.

- **Version:** 5.6.2

[![Build Status](https://camo.githubusercontent.com/cf7cf71011198b641980dc3d60d606df43a6871875b618732cd855d8f9be5774/68747470733a2f2f7472617669732d63692e6f72672f6d6f6e676572696e632f7365617263682d726571756573742e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/mongerinc/search-request)

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Usage](#usage)
    - [JSON](#json)
    - [Selection](#selection)
    - [Sorting](#sorting)
    - [Grouping](#grouping)
    - [Pagination](#pagination)
    - [Filtering](#filtering)
    - [Faceting](#faceting)
    - [Field Substitution](#field-substitution)
- [Examples](#examples)

### Installation

[](#installation)

Install SearchRequest via composer by adding the following to the `require` block in your `composer.json` file:

```
"mongerinc/search-request": "5.*"

```

### Usage

[](#usage)

When creating a `SearchRequest` from scratch, you first need to instantiate a request:

```
$request = new SearchRequest;

//or

$request = SearchRequest::create();

//or call any method statically

$request = SearchRequest::where('something', true);
```

As a starting point, each search request has no sorts, no filters, and no groupings. Pagination starts at page 1 and by default there is a limit of 10 rows per page.

#### JSON

[](#json)

Using the `toJson()` method, each `SearchRequest` instance can be compiled into a JSON string that you can use to communicate across application boundaries.

```
$request->toJson();

```

Likewise, you can build a new `SearchRequest` instance using a JSON string that was compiled by a `SearchRequest` instance.

```
$request = new SearchRequest($json);

```

#### Selection

[](#selection)

The most common method of setting selections on the request is by using the `select()` method which overrides any existing selects:

```
$request->select(['field1', 'field2']);
```

If you want to add to existing selects, you can call the `addSelect()` method instead. You can chain this method:

```
$request->addSelect('field1')->addSelect('field2');
```

Retrieving the set of selects is done by the `getSelects()` method.

```
$request->getSelects();
```

#### Sorting

[](#sorting)

The most common method of sorting the request is by using the `sort()` method which overrides any existing sorts:

```
$request->sort('field', 'asc');
```

The first parameter in any sort call is the string field and the second parameter is the sort direction which is limited to `asc` and `desc`.

If you want to create a request with multiple sorts, you can call the `addSort()` method instead. You can chain this method:

```
$request->addSort('field', 'asc')->addSort('otherField', 'desc');
```

If you want to retrieve the sorts, you can either call the `getSort()` method to get the primary sort, or you can call `getSorts()` to get the array of all sorts. Each sort is represented by a `Sort` instance where you can ask for the field and the direction:

```
$sort = $request->getSort();

$databaseQuery->orderBy($sort->getField(), $sort->getDirection());
```

#### Grouping

[](#grouping)

Grouping a `SearchRequest` can be done using the `groupBy()` method. The `groupBy()` method takes either a string or an array of strings as an input. The method can also be chained.

```
$request->groupBy('field')->groupBy('anotherField');

$request->groupBy(['field', 'anotherField']);
```

Retrieving the set of groups is done by the `getGroups()` method.

```
$request->getGroups();
```

#### Pagination

[](#pagination)

Creating a new `SearchRequest` defaults to page 1 and a limit of 10 rows per page. If you want to modify this, you can call the `page()` and `limit()` methods:

```
$request->page(5)->limit(40);
```

If you want to simply go to the next page, you can call the `nextPage()` method and it will increment the current page by 1.

Retrieving the page and limit is done by the methods `getPage()` and `getLimit()`:

```
$limit = $request->getLimit();
$page = $request->getPage();

$databaseQuery->take($limit)->skip(($page - 1) * $limit);
```

Alternatively, you can call `getSkip()` to avoid doing the calculation above.

If you want to ignore the pagination for a request, you can call the `unlimited()` or `all()` methods.

```
$request = $request->unlimited();

if (!$request->isUnlimited())
   $databaseQuery->take($request->getLimit())->skip($request->getSkip());
```

The unlimited feature is only a flag. Your database query applier must check for this with the `isUnlimited()` method to support this feature.

#### Filtering

[](#filtering)

Filtering a `SearchRequest` can be done using the `where()` method. An operator can be provided as the second argument where the possible types are `=`, `>`, `>=`, `where('isFun', true);            //assumed to be an equality
```

Each of the word-like operators (`in`, `like`, `regex, `exists`, `between`) has a set of four companion helper methods. These follow this general format:

```
$request->where{Word}($field, $value)
        ->orWhere{Word}($field, $value)
        ->whereNot{Word}($field, $value)
        ->orWhereNot{Word}($field, $value);

//example:
$request->whereLike($field, $value)
        ->orWhereLike($field, $value)
        ->whereNotLike($field, $value)
        ->orWhereNotLike($field, $value);
```

Reading filters from the search request can be done using the `getFilters()` method:

```
foreach ($request->getFilters() as $filter)
{
	$databaseQuery->where($filter->getField(), $filter->getOperator(), $filter->getValue());
}
```

You can also call `getFilter($field)` or `getFilterValue($field)` on the `SearchRequest` or `FilterSet` to get the `Filter`/value respectively of the first filter that matches that field name. This is useful if your filters are relatively simple and you only expect one value for each field name.

```
$request->where('foo', true);
$request->where('foo', '>', 5);

$request->getFilterValue('foo'); //true
$request->getFilters()->getFilterValue('foo'); //true
```

More complex filtering can be accomplished by using nested conditions. Assuming you wanted to make a request representing the following pseudo-SQL conditional statement:

```
...WHERE goodTimes = true AND (profit > 1000 OR revenue > 1000000)
```

...you would do the following...

```
$request->where('goodTimes', true)
        ->where(function($filterSet)
        {
            $filterSet->where('profit', '>', 1000)
                      ->orWhere('revenue', '>', 1000000);
        });
```

When reading a complex set of conditionals back from the `SearchRequest`, there are several important concepts to understand:

1. Each nesting layer (including the top layer) is represented by a `FilterSet`. A `FilterSet` has a boolean (and/or) and can be comprised of any combination of `Filter` and `FilterSet` objects. These objects are provided in the order they were entered.
2. A `Filter` object represents a field, value, and conditional operator along with a boolean (and/or).

Since the nesting of conditionals is theoretically infinite, you may want to implement a recursive function to apply the request to the library of your choice (like a database query builder). An example of this can be seen in the `/examples` directory.

It's also possible to remove filters by name:

```
$request->where('foo', 1)->where('moo', 2)->where('goo', 3);

$request->removeFilters('foo')->removeFilters(['moo', 'goo']);
```

#### Faceting

[](#faceting)

Faceting (i.e. getting attribute values and their counts) a `SearchRequest` can be done like this:

```
$facet = $request->facet('someField');
```

This will create a facet for `someField` and, unlike other methods, returns a `Facet` instance instead of the `SearchRequest`. You can also create multiple facets at once:

```
$request->addFacets(['someField', 'someOtherField']);
```

And you can get facets either one at a time by field name (will only return the first match):

```
$request->getFacet('someField');
```

Or all at once:

```
$request->getFacets();
```

Sorting a facet's results can be done either by count or value (the default) and a direction.

```
$facet->isCountSorting(); //bool
$facet->isValueSorting(); //bool
$facet->getSortDirection(); //'asc' or 'desc'

$facet->sortByCount();
$facet->sortByValue();
$facet->setSortDirection('asc');
```

The minimum number of values a facet field must have in order to be returned in the result set is 1.

```
$facet->getMinimumCount(); //1

$facet->setMinimumCount(5);
```

Filters that exist for the facet's field are by default excluded from consideration when building the facet results.

```
$facet->shouldExcludeOwnFilters(); //true

$facet->excludeOwnFilters();
$facet->includeOwnFilters();
```

A facet can also be paginated just like the search request and with the same default values:

```
$facet->getPage();
$facet->getLimit();
$facet->getSkip();

$facet->page(5)->limit(100);
$facet->nextPage();
```

#### Field Substitution

[](#field-substitution)

When making search requests, you often want to keep the specifics of a data storage schema hidden from the rest of your code base. For example, you may have a denormalized SQL field called `category_name` on your `products` table that on the way out gets formatted as:

```
[
	...
	'category' => [
		'id' => $product->category_id,
		'name' => $product->category_name,
	],
	...
]
```

So the rest of your system sees `category.name` as the field, but your SQL repository only understands `category_name`. This is where field substitution comes in handy:

```
//abstract layer code
$request->where('category.name', 'Foo');

//then later in the repository
$request->substituteField('category.name', 'category_name');
```

You can also substitute many fields at once by passing in an array of `original` =&gt; `substitution` values:

```
$request->substituteFields(
	['category.name' => 'category_name'],
	['category.id' => 'category_id'],
);
```

### Examples

[](#examples)

At the root of this project there is an `/examples` directory that contains a few examples of how you would apply search requests to database queries. As this project was inspired by Laravel's query builder, one example shows how to leverage SearchRequest to apply complex parameter sets to it in a reusable way. Using the same approach, SearchRequest can be used to apply complex parameter sets to any library that needs them (e.g. MongoDB, Solr, etc.).

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 82.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~46 days

Total

25

Last Release

2877d ago

Major Versions

v1.2.0 → v2.0.02017-07-01

v2.1.0 → v3.0.02017-07-07

v3.3.0 → v4.0.02017-08-02

v4.0.0 → v5.0.02017-08-03

v5.6.2 → v6.0.02018-06-28

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/580052?v=4)[Jan Hartigan](/maintainers/janhartigan)[@janhartigan](https://github.com/janhartigan)

---

Top Contributors

[![janhartigan](https://avatars.githubusercontent.com/u/580052?v=4)](https://github.com/janhartigan "janhartigan (37 commits)")[![sdsomma](https://avatars.githubusercontent.com/u/1578898?v=4)](https://github.com/sdsomma "sdsomma (7 commits)")[![rachellej](https://avatars.githubusercontent.com/u/6774640?v=4)](https://github.com/rachellej "rachellej (1 commits)")

---

Tags

requestsearchpaginationqueryfiltergroup

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mongerinc-search-request/health.svg)

```
[![Health](https://phpackages.com/badges/mongerinc-search-request/health.svg)](https://phpackages.com/packages/mongerinc-search-request)
```

###  Alternatives

[netgen/query-translator

Query Translator is a search query translator with AST representation

2042.0M6](/packages/netgen-query-translator)[friendsofcake/search

CakePHP Search plugin using PRG pattern

1742.0M37](/packages/friendsofcake-search)[mehradsadeghi/laravel-filter-querystring

Filter your queries based on url query string parameters like a breeze.

169118.2k](/packages/mehradsadeghi-laravel-filter-querystring)[outl1ne/nova-input-filter

An input filter for Laravel Nova

24822.7k](/packages/outl1ne-nova-input-filter)[optimistdigital/nova-input-filter

An input filter for Laravel Nova

24550.6k2](/packages/optimistdigital-nova-input-filter)[skie/cakephp-search

CakePHP Plum Search plugin

19186.5k2](/packages/skie-cakephp-search)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
