# Making queries

With queries, you can easily filter, retrieve and delete multiple entries from the database. To keep things simple, HivePress implements a common API for all the WordPress query types (e.g. `WP_Query`, `WP_Comment_Query`, `WP_Term_Query`).

Let's take a look at the main query operations. We use the `Listing` model in the examples below, but the API is the same for all models. You can always check the available models in the `includes/models` subdirectory of HivePress or its extensions.

### Quick example <a href="#bkmrk-quick-example" id="bkmrk-quick-example"></a>

The code example below gets three featured listings from a specific category and orders them by the creation date. Then each listing is updated with the "Custom text" title, and finally, all listings are deleted.

```php
// Query listings.
$listings = HivePress\Models\Listing::query()->filter(
	[
		'featured'       => true,
		'categories__in' => [ 123 ],
	]
)->order( [ 'created_date' => 'desc' ] )
->limit( 3 )
->get();

// Update listings.
foreach ( $listings as $listing ) {
	$listing->set_title( 'Custom text' )->save_title();
}

// Delete listings.
$listings->delete();
```

### Creating queries <a href="#bkmrk-creating-queries" id="bkmrk-creating-queries"></a>

To create a query object, call the static `query` method on the `HivePress\Models\{Model_Name}` class:

```php
$query = HivePress\Models\Listing::query();
```

After the object is created, you can start building the query. Please note that the database will not be queried until you call one of the methods for retrieving results.

### Filtering results <a href="#bkmrk-filtering-results" id="bkmrk-filtering-results"></a>

For filtering the results, call the `filter` method with an array where keys are field names and values are used for comparison:

```php
$query->filter(
	[
		'status'   => 'publish',
		'verified' => true,
	]
);
```

The default comparison operator is `=`, but the following operators are also available:

* `not` (!=)
* `gt` (>)
* `gte` (>=)
* `lt` (<)
* `lte` (<=)
* `like`
* `not_like`
* `in`
* `not_in`
* `between`
* `not_between`
* `exists`
* `not_exists`

To use the comparison operator, add it to the field name via the double underscore:

```php
// Filter listings by ID.
$query->filter(
	[
		'id__in' => [ 1, 2, 3 ],
	]
);

// Filter listings with rating > 3.
$query->filter(
	[
		'rating__gt' => 3,
	]
);

// Filter listings with an image.
$query->filter(
	[
		'image__exists' => true,
	]
);
```

Also, you can use the `search` method to search results. For example, the code below searches listings with the "foobar" word in the listing title or description:

```php
$query->search( 'foobar' );
```

Since HivePress doesn't fully replace the WordPress query API, you may need to set some WordPress-level arguments depending on the underlying query type (e.g. `WP_Query`). To do this, simply call the `set_args` method with an array of the WordPress-level query arguments:

```php
$query->set_args(
	[
		'meta_key'   => 'custom_field',
		'meta_value' => 123,
	]
);
```

Similarly, if you build a query object with the HivePress API, you can get an array of WordPress-level query arguments using the `get_args` method (e.g. for passing to `WP_Query`):

```php
$args = $query->get_args();
```

### Ordering results <a href="#bkmrk-ordering-results" id="bkmrk-ordering-results"></a>

To order the query results, call the `order` method with an array where keys are field names and values define the sorting order (`asc` for ascending, `desc` for descending):

```php
$query->order( [ 'created_date' => 'desc' ] );
```

If you filter results by ID and want them to follow the same order, pass the `id__in` argument:

```php
$query->order( 'id__in' );
```

Also, if the query model inherits the `Post` class, you can set a random order:

```php
$query->order( 'random' );
```

### Limiting results <a href="#bkmrk-limiting-results" id="bkmrk-limiting-results"></a>

To limit the number of results, use the `limit` method:

```php
$query->limit( 123 );
```

For retrieving results starting from a specific position, call the `offset` method:

```php
$query->offset( 123 );
```

To paginate results based on the limit, use the `paginate` method with the page number:

```php
$query->paginate( 123 );
```

### Retrieving results <a href="#bkmrk-retrieving-results" id="bkmrk-retrieving-results"></a>

Once the query is ready, call the `get` method to retrieve entries from the database:

```php
$listings = $query->get();
```

It returns an array-like object that you can iterate over (e.g. with `foreach` loop) or check the result count using the `count` method. If you need a regular array, call the `serialize` method:

```php
$listings = $listings->serialize();
```

Also, you can chain query methods for better code readability:

```php
$listings = $query->get()->serialize();
```

To get the IDs only, use the `get_ids` method instead:

```php
$listing_ids = $query->get_ids();
```

For the first result only, call the `get_first` method:

```php
$listing = $query->get_first();
```

To get its ID only, use the `get_first_id` method:

```php
$listing_id = $query->get_first_id();
```

To get the result count only, call the `get_count` method instead:

```php
$listing_count = $query->get_count();
```

For retrieving a single result by ID, call the `get_by_id` method directly:

```php
$listing = HivePress\Models\Listing::query()->get_by_id( 123 );
```

### Updating results <a href="#bkmrk-updating-results" id="bkmrk-updating-results"></a>

Currently, there's no method for updating results in bulk, but you can iterate over the model objects and update them separately:

```php
foreach ( $listings as $listing ) {
	$listing->fill(
		[
			'title'    => 'Custom title',
			'featured' => true,
		]
	)->save( [ 'title', 'featured' ] );
}
```

### Deleting results <a href="#bkmrk-deleting-results" id="bkmrk-deleting-results"></a>

To delete the query results from the database, call the `delete` method:

```php
$query->delete();
```

Also, if the query model inherits the `Post` or `Comment` classes, you can move results to **Trash**:

```php
$query->trash();
```

For deleting a single result without retrieving it, call the `delete_by_id` method directly:

```php
HivePress\Models\Listing::query()->delete_by_id( 123 );
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hivepress.io/developer-docs/framework/models/making-queries.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
