> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Filter by attributes

> How to use Algolia to filter content

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

Filters can work with strings, numbers, boolean values, dates, tags, or lists.

<Note>
  [Add filters to your UI](/doc/guides/managing-results/refine-results/filtering#how-to-apply-filtering-to-the-search-ui) with InstantSearch widgets or your own custom code.
</Note>

## Filter by string

[Example dataset](#example-dataset)

Algolia lets you filter search results by string attributes. For example, users of an online bookstore might want to search for books from different publishers. With [filters](/doc/guides/managing-results/refine-results/filtering), they can refine results by:

* Showing books published by Penguin
* Showing books published by Bloomsbury or Scribe
* Showing all books except those published by Penguin

### Apply a string filter

To run the code examples on this page, [install the latest API client](/doc/libraries/sdk/install).

Set `author` as an [attribute for faceting](/doc/guides/managing-results/refine-results/filtering#define-filterable-attributes), then apply your string filters with the [`filters`](/doc/api-reference/api-parameters/filters) parameter in your [`search`](/doc/libraries/sdk/v1/methods/search) code:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(
      new SearchParamsObject
      {
        FacetFilters = new FacetFilters(
          new List<FacetFilters>
          {
            new FacetFilters("publisher:Penguin"),
            new FacetFilters(
              new List<FacetFilters>
              {
                new FacetFilters("author:Stephen King"),
                new FacetFilters("genre:Horror"),
              }
            ),
          }
        ),
      }
    )
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      facetFilters: [
        "publisher:Penguin",
        [
          "author:Stephen King",
          "genre:Horror",
        ],
      ],
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetFacetFilters(search.ArrayOfFacetFiltersAsFacetFilters(
      []search.FacetFilters{*search.StringAsFacetFilters("publisher:Penguin"), *search.ArrayOfFacetFiltersAsFacetFilters(
        []search.FacetFilters{*search.StringAsFacetFilters("author:Stephen King"), *search.StringAsFacetFilters("genre:Horror")})})))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex(
    "INDEX_NAME",
    new SearchParamsObject().setFacetFilters(
      FacetFilters.of(
        Arrays.asList(
          FacetFilters.of("publisher:Penguin"),
          FacetFilters.of(Arrays.asList(FacetFilters.of("author:Stephen King"), FacetFilters.of("genre:Horror")))
        )
      )
    ),
    Hit.class
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: 'indexName',
    searchParams: { facetFilters: ['publisher:Penguin', ['author:Stephen King', 'genre:Horror']] },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams =
        SearchParamsObject(
          facetFilters =
            FacetFilters.of(
              listOf(
                FacetFilters.of("publisher:Penguin"),
                FacetFilters.of(
                  listOf(FacetFilters.of("author:Stephen King"), FacetFilters.of("genre:Horror"))
                ),
              )
            )
        ),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['facetFilters' => [
          'publisher:Penguin',

          [
              'author:Stephen King',

              'genre:Horror',
          ],
      ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "facetFilters": [
              "publisher:Penguin",
              [
                  "author:Stephen King",
                  "genre:Horror",
              ],
          ],
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(
      facet_filters: ["publisher:Penguin", ["author:Stephen King", "genre:Horror"]]
    )
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          facetFilters = Some(
            FacetFilters(
              Seq(
                FacetFilters("publisher:Penguin"),
                FacetFilters(Seq(FacetFilters("author:Stephen King"), FacetFilters("genre:Horror")))
              )
            )
          )
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams
          .searchSearchParamsObject(SearchSearchParamsObject(facetFilters: SearchFacetFilters
                  .arrayOfSearchFacetFilters([
                      SearchFacetFilters.string("publisher:Penguin"),
                      SearchFacetFilters.arrayOfSearchFacetFilters([
                          SearchFacetFilters.string("author:Stephen King"),
                          SearchFacetFilters.string("genre:Horror"),
                      ]),
                  ])))
  )
  ```
</CodeGroup>

## Filter by numeric value

Algolia lets you numerically filter results with a comparison or a range.
This only works with numeric values.
For example, you could allow users to only show books that cost less than a certain price or those in a specific price range.

**The `price` attribute is a numeric attribute, not a string attribute**.

### Apply a numeric filter

[Example dataset](#example-dataset)

Using the example dataset, you've decided to let users define a price limit. For example, they may only want books that cost less than \$10:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(new SearchParamsObject { Filters = "price < 10" })
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      filters: "price < 10",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetFilters("price < 10"))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex("INDEX_NAME", new SearchParamsObject().setFilters("price < 10"), Hit.class);
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({ indexName: 'indexName', searchParams: { filters: 'price < 10' } });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = SearchParamsObject(filters = "price < 10"),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['filters' => 'price < 10',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "filters": "price < 10",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(filters: "price < 10")
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          filters = Some("price < 10")
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(filters: "price < 10"))
  )
  ```
</CodeGroup>

Algolia filters use an SQL-like syntax, which lets you use comparison operator attributes: `<`, `<=`, `=`, `!=`, `>=`, and `>`.

To allow users to retrieve books between a range, say $10 and $20, set a range filter:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(new SearchParamsObject { Query = "books", Filters = "price:10 TO 20" })
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      query: "books",
      filters: "price:10 TO 20",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetQuery("books").SetFilters("price:10 TO 20"))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex(
    "INDEX_NAME",
    new SearchParamsObject().setQuery("books").setFilters("price:10 TO 20"),
    Hit.class
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: 'indexName',
    searchParams: { query: 'books', filters: 'price:10 TO 20' },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = SearchParamsObject(query = "books", filters = "price:10 TO 20"),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['query' => 'books',
          'filters' => 'price:10 TO 20',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "query": "books",
          "filters": "price:10 TO 20",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(query: "books", filters: "price:10 TO 20")
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          query = Some("books"),
          filters = Some("price:10 TO 20")
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(
          query: "books",
          filters: "price:10 TO 20"
      ))
  )
  ```
</CodeGroup>

## Filter by date

[Example dataset](#example-dataset)

As well as [sorting](/doc/guides/managing-results/refine-results/sorting/how-to/sort-an-index-by-date), you can use dates to **filter search results within a specific period**. For example, you can allow users to filter on recently published books or only see books published within a certain period.

### Format your dates suitably

Algolia can filter on date attributes,
but they must be formatted as [Unix timestamps](https://wikipedia.org/wiki/Unix_time).
For more information, see [Formatting dates](/doc/guides/sending-and-managing-data/prepare-your-data/in-depth/what-is-in-a-record#dates)

Instead of changing the date attribute, you could add an additional timestamp attribute.
In the example dataset,
the `publication_date` attribute has the formatted date for display, while the `date_timestamp` attribute can be used for filtering.

### Apply a date filter

With dates represented as Unix timestamp, use the [`filters`](/doc/api-reference/api-parameters/filters) parameter to only retrieve some results. For example:

* [Recently published books](#recently-published-books)
* [Books for a particular year](#books-for-a-particular-year)
* [Closest dates](#closest-dates)

#### Recently published books

If you want users to filter for recent books, decide what recent means to you.
For example, a recent book might be a book published less than a year ago.
This means you must set a filter that excludes <Records /> with `date_timestamp` greater than now minus one year.

<CodeGroup>
  ```cs C# theme={"system"}
  namespace Algolia;

  using System;
  using System.Collections.Generic;
  using System.Net.Http;
  using System.Text.Json;
  using Algolia.Search.Clients;
  using Algolia.Search.Http;
  using Algolia.Search.Models.Search;

  class SearchRecentlyPublishedBooks
  {
    async Task Main(string[] args)
    {
      var client = new SearchClient(new SearchConfig("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY"));
      var date = DateTime.UtcNow.AddYears(-1);
      var sTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
      var unixTime = (long)(date - sTime).TotalSeconds;
      var searchParams = new SearchParams(
        new SearchParamsObject
        {
          Query = "SEARCH_QUERY",
          Filters = $"date_timestamp > {unixTime}",
        }
      );

      await client.SearchSingleIndexAsync<Hit>("INDEX_NAME", searchParams);
    }
  }

  ```

  ```dart Dart theme={"system"}
  import 'package:algolia_client_search/algolia_client_search.dart';

  void searchRecentlyPublishedBooks() async {
    final client =
        SearchClient(appId: 'ALGOLIA_APPLICATION_ID', apiKey: 'ALGOLIA_API_KEY');

    final dateTimestamp =
        DateTime.now().subtract(Duration(days: 365)).millisecondsSinceEpoch;
    final searchParams = SearchParamsObject(
        query: "SEARCH_QUERY", filters: "date_timestamp > $dateTimestamp");

    await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: searchParams,
    );
  }

  ```

  ```go Go theme={"system"}
  package main

  import (
  	"fmt"
  	"time"

  	"github.com/algolia/algoliasearch-client-go/v4/algolia/search"
  )

  func searchRecentlyPublishedBooks() {
  	client, err := search.NewClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
  	if err != nil {
  		// The client can fail to initialize if you pass an invalid parameter.
  		panic(err)
  	}

  	dateTimestamp := time.Now().AddDate(-1, 0, 0).Unix()
  	searchParams := search.SearchParamsObjectAsSearchParams(
  		search.NewSearchParamsObject().
  			SetQuery("SEARCH_QUERY").
  			SetFilters(fmt.Sprintf("date_timestamp > %d", dateTimestamp)),
  	)

  	_, err = client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
  		"INDEX_NAME").WithSearchParams(searchParams))
  	if err != nil {
  		panic(err)
  	}
  }

  ```

  ```java Java theme={"system"}
  package com.algolia;

  import com.algolia.api.SearchClient;
  import com.algolia.config.*;
  import com.algolia.model.search.*;
  import java.time.ZoneOffset;
  import java.time.ZonedDateTime;

  public class searchRecentlyPublishedBooks {

    public static void main(String[] args) throws Exception {
      try (SearchClient client = new SearchClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")) {
        long dateTimestamp = ZonedDateTime.now(ZoneOffset.UTC).plusYears(-1).toEpochSecond();
        SearchParams searchParams = new SearchParamsObject().setQuery("SEARCH_QUERY").setFilters("date_timestamp > " + dateTimestamp);

        client.searchSingleIndex("INDEX_NAME", searchParams, Hit.class);
      } catch (Exception e) {
        System.out.println("An error occurred: " + e.getMessage());
      }
    }
  }

  ```

  ```js JavaScript theme={"system"}
  import { algoliasearch } from 'algoliasearch';

  import type { SearchParams } from 'algoliasearch';

  const client = algoliasearch('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');

  const d = new Date();
  const searchParams: SearchParams = {
    query: 'SEARCH_QUERY',
    filters: `date_timestamp > ${Math.floor(d.setDate(d.getDate() - 365) / 1000)}`,
  };

  await client.searchSingleIndex({ indexName: 'indexName', searchParams: searchParams });

  ```

  ```kotlin Kotlin theme={"system"}
  import com.algolia.client.api.SearchClient
  import com.algolia.client.configuration.*
  import com.algolia.client.extensions.*
  import com.algolia.client.model.search.*
  import com.algolia.client.transport.*
  import java.time.Instant
  import java.time.temporal.ChronoUnit

  suspend fun searchRecentlyPublishedBooks() {
    val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")

    val dateTimestamp = Instant.now().minus(365, ChronoUnit.DAYS).epochSecond
    val searchParams =
      SearchParamsObject(query = "SEARCH_QUERY", filters = "date_timestamp > $dateTimestamp")

    client.searchSingleIndex(indexName = "INDEX_NAME", searchParams = searchParams)
  }

  ```

  ```php PHP theme={"system"}
  <?php

  require __DIR__.'/../vendor/autoload.php';
  use Algolia\AlgoliaSearch\Api\SearchClient;
  use Algolia\AlgoliaSearch\Model\Search\SearchParamsObject;

  $client = SearchClient::create('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');

  $dateTimestamp = strtotime('-1 years');
  $searchParams = (new SearchParamsObject())
      ->setQuery('SEARCH_QUERY')
      ->setFilters('date_timestamp > '.$dateTimestamp)
  ;

  $client->searchSingleIndex(
      'INDEX_NAME',
      $searchParams,
  );

  ```

  ```python Python theme={"system"}
  import datetime
  import time

  from algoliasearch.search.client import SearchClientSync


  _client = SearchClientSync("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")


  date = datetime.datetime.now() - datetime.timedelta(days=365)
  date_timestamp = int(time.mktime(date.timetuple()))
  search_params = {
      "query": "SEARCH_QUERY",
      "filters": f"date_timestamp > {date_timestamp}",
  }

  _client.search_single_index(
      index_name="INDEX_NAME",
      search_params=search_params,
  )

  ```

  ```ruby Ruby theme={"system"}
  import(time)

  require "algolia"

  client = Algolia::SearchClient.create("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")

  date_timestamp = Time.now.to_i - 60 * 60 * 24 * 365
  search_params = Algolia::Search::SearchParamsObject.new(
    query: "SEARCH_QUERY",
    filters: "date_timestamp > #{date_timestamp}"
  )

  client.search_single_index("INDEX_NAME", search_params)

  ```

  ```scala Scala theme={"system"}
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.Future
  import java.time.{Instant, LocalDateTime, ZoneOffset}

  import algoliasearch.api.SearchClient
  import algoliasearch.config.*
  import algoliasearch.extension.SearchClientExtensions
  import algoliasearch.search.SearchParamsObject

  def searchRecentlyPublishedBooks(): Future[Unit] = {
    val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")

    val dateTimestamp = LocalDateTime.now().minusYears(1).toInstant(ZoneOffset.UTC).getEpochSecond
    val searchParams = SearchParamsObject(
      query = Some("SEARCH_QUERY"),
      filters = Some(s"date_timestamp > $dateTimestamp")
    )

    client
      .searchSingleIndex(
        indexName = "INDEX_NAME",
        searchParams = Some(searchParams)
      )
      .map { response =>
        println(response)
      }
      .recover { case ex: Exception =>
        println(s"An error occurred: ${ex.getMessage}")
      }
  }

  ```

  ```swift Swift theme={"system"}
  import Foundation
  #if os(Linux) // For linux interop
      import FoundationNetworking
  #endif

  import AlgoliaCore
  import AlgoliaSearch

  func searchRecentlyPublishedBooks() async throws {
      let client = try SearchClient(appID: "ALGOLIA_APPLICATION_ID", apiKey: "ALGOLIA_API_KEY")

      let dateTimestamp = Int(Date().timeIntervalSince1970) - 365 * 24 * 60 * 60
      let searchParams = SearchSearchParams.searchSearchParamsObject(
          SearchSearchParamsObject(query: "SEARCH_QUERY", filters: "date_timestamp > \(dateTimestamp)")
      )

      let response: SearchResponse<Hit> = try await client.searchSingleIndex(
          indexName: "INDEX_NAME",
          searchParams: searchParams
      )
      print(response)
  }

  ```
</CodeGroup>

Algolia filters use an SQL-like syntax, which lets you use comparison operators: `<`, `<=`, `=`, `!=`, `>=`, and `>`.

#### Books for a particular year

If you want to only retrieve books from 2018, set a range filter and provide it with Unix timestamps for the first and last day of the year. If you want to exclude a particular year or search for all books published outside a specific time you can combine time periods with the `NOT` boolean operator:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(
      new SearchParamsObject { Filters = "NOT date_timestamp:1514764800 TO 1546300799" }
    )
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      filters: "NOT date_timestamp:1514764800 TO 1546300799",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetFilters("NOT date_timestamp:1514764800 TO 1546300799"))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex(
    "INDEX_NAME",
    new SearchParamsObject().setFilters("NOT date_timestamp:1514764800 TO 1546300799"),
    Hit.class
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: 'indexName',
    searchParams: { filters: 'NOT date_timestamp:1514764800 TO 1546300799' },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = SearchParamsObject(filters = "NOT date_timestamp:1514764800 TO 1546300799"),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['filters' => 'NOT date_timestamp:1514764800 TO 1546300799',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "filters": "NOT date_timestamp:1514764800 TO 1546300799",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(filters: "NOT date_timestamp:1514764800 TO 1546300799")
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          filters = Some("NOT date_timestamp:1514764800 TO 1546300799")
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams
          .searchSearchParamsObject(
              SearchSearchParamsObject(filters: "NOT date_timestamp:1514764800 TO 1546300799")
          )
  )
  ```
</CodeGroup>

#### Closest dates

If your <Index /> contains books that will be published in the future, it can be helpful to [sort results from sooner to later](/doc/guides/managing-results/refine-results/sorting/how-to/sort-an-index-by-date), so that users will see the next published books first.

<Steps>
  <Step title="Sort records">
    Sort records by ascending date so that books due to be published later sit lower in the search results:

    <CodeGroup>
      ```cs C# theme={"system"}
      var response = await client.SetSettingsAsync(
        "INDEX_NAME",
        new IndexSettings
        {
          Ranking = new List<string>
          {
            "asc(date_timestamp)",
            "typo",
            "geo",
            "words",
            "filters",
            "proximity",
            "attribute",
            "exact",
            "custom",
          },
        }
      );
      ```

      ```dart Dart theme={"system"}
      final response = await client.setSettings(
        indexName: "INDEX_NAME",
        indexSettings: IndexSettings(
          ranking: [
            "asc(date_timestamp)",
            "typo",
            "geo",
            "words",
            "filters",
            "proximity",
            "attribute",
            "exact",
            "custom",
          ],
        ),
      );
      ```

      ```go Go theme={"system"}
      response, err := client.SetSettings(client.NewApiSetSettingsRequest(
        "INDEX_NAME",
        search.NewEmptyIndexSettings().SetRanking(
          []string{"asc(date_timestamp)", "typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom"})))
      if err != nil {
        // handle the eventual error
        panic(err)
      }
      ```

      ```java Java theme={"system"}
      UpdatedAtResponse response = client.setSettings(
        "INDEX_NAME",
        new IndexSettings().setRanking(
          Arrays.asList("asc(date_timestamp)", "typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom")
        )
      );
      ```

      ```js JavaScript theme={"system"}
      const response = await client.setSettings({
        indexName: 'theIndexName',
        indexSettings: {
          ranking: ['asc(date_timestamp)', 'typo', 'geo', 'words', 'filters', 'proximity', 'attribute', 'exact', 'custom'],
        },
      });
      ```

      ```kotlin Kotlin theme={"system"}
      var response =
        client.setSettings(
          indexName = "INDEX_NAME",
          indexSettings =
            IndexSettings(
              ranking =
                listOf(
                  "asc(date_timestamp)",
                  "typo",
                  "geo",
                  "words",
                  "filters",
                  "proximity",
                  "attribute",
                  "exact",
                  "custom",
                )
            ),
        )
      ```

      ```php PHP theme={"system"}
      $response = $client->setSettings(
          'INDEX_NAME',
          ['ranking' => [
              'asc(date_timestamp)',

              'typo',

              'geo',

              'words',

              'filters',

              'proximity',

              'attribute',

              'exact',

              'custom',
          ],
          ],
      );
      ```

      ```python Python theme={"system"}
      response = client.set_settings(
          index_name="INDEX_NAME",
          index_settings={
              "ranking": [
                  "asc(date_timestamp)",
                  "typo",
                  "geo",
                  "words",
                  "filters",
                  "proximity",
                  "attribute",
                  "exact",
                  "custom",
              ],
          },
      )
      ```

      ```ruby Ruby theme={"system"}
      response = client.set_settings(
        "INDEX_NAME",
        Algolia::Search::IndexSettings.new(
          ranking: ["asc(date_timestamp)", "typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom"]
        )
      )
      ```

      ```scala Scala theme={"system"}
      val response = Await.result(
        client.setSettings(
          indexName = "INDEX_NAME",
          indexSettings = IndexSettings(
            ranking = Some(
              Seq("asc(date_timestamp)", "typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom")
            )
          )
        ),
        Duration(100, "sec")
      )
      ```

      ```swift Swift theme={"system"}
      let response = try await client.setSettings(
          indexName: "INDEX_NAME",
          indexSettings: IndexSettings(ranking: [
              "asc(date_timestamp)",
              "typo",
              "geo",
              "words",
              "filters",
              "proximity",
              "attribute",
              "exact",
              "custom",
          ])
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Remove older titles">
    Filter out every record with past dates:

    <CodeGroup>
      ```cs C# theme={"system"}
      namespace Algolia;

      using System;
      using System.Collections.Generic;
      using System.Net.Http;
      using System.Text.Json;
      using Algolia.Search.Clients;
      using Algolia.Search.Http;
      using Algolia.Search.Models.Search;

      class SearchFuturePublishedBooks
      {
        async Task Main(string[] args)
        {
          var client = new SearchClient(new SearchConfig("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY"));
          var dateTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
          var searchParams = new SearchParams(
            new SearchParamsObject
            {
              Query = "SEARCH_QUERY",
              Filters = $"date_timestamp > {dateTimestamp}",
            }
          );

          await client.SearchSingleIndexAsync<Hit>("INDEX_NAME", searchParams);
        }
      }

      ```

      ```dart Dart theme={"system"}
      import 'package:algolia_client_search/algolia_client_search.dart';

      void searchFuturePublishedBooks() async {
        final client =
            SearchClient(appId: 'ALGOLIA_APPLICATION_ID', apiKey: 'ALGOLIA_API_KEY');

        final dateTimestamp = DateTime.now().millisecondsSinceEpoch;
        final searchParams = SearchParamsObject(
            query: "SEARCH_QUERY", filters: "date_timestamp > $dateTimestamp");

        await client.searchSingleIndex(
          indexName: "INDEX_NAME",
          searchParams: searchParams,
        );
      }

      ```

      ```go Go theme={"system"}
      package main

      import (
      	"fmt"
      	"time"

      	"github.com/algolia/algoliasearch-client-go/v4/algolia/search"
      )

      func searchFuturePublishedBooks() {
      	client, err := search.NewClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
      	if err != nil {
      		// The client can fail to initialize if you pass an invalid parameter.
      		panic(err)
      	}

      	dateTimestamp := time.Now().UnixMilli()
      	searchParams := search.SearchParamsObjectAsSearchParams(
      		search.NewSearchParamsObject().
      			SetQuery("SEARCH_QUERY").
      			SetFilters(fmt.Sprintf("date_timestamp > %d", dateTimestamp)),
      	)

      	_, err = client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
      		"INDEX_NAME").WithSearchParams(searchParams))
      	if err != nil {
      		panic(err)
      	}
      }

      ```

      ```java Java theme={"system"}
      package com.algolia;

      import com.algolia.api.SearchClient;
      import com.algolia.config.*;
      import com.algolia.model.search.*;

      public class searchFuturePublishedBooks {

        public static void main(String[] args) throws Exception {
          try (SearchClient client = new SearchClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")) {
            long dateTimestamp = System.currentTimeMillis();
            SearchParams searchParams = new SearchParamsObject().setQuery("SEARCH_QUERY").setFilters("date_timestamp > " + dateTimestamp);

            client.searchSingleIndex("INDEX_NAME", searchParams, Hit.class);
          } catch (Exception e) {
            System.out.println("An error occurred: " + e.getMessage());
          }
        }
      }

      ```

      ```js JavaScript theme={"system"}
      import { algoliasearch } from 'algoliasearch';

      import type { SearchParams } from 'algoliasearch';

      const client = algoliasearch('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');

      const dateTimestamp = Date.now();
      const searchParams: SearchParams = {
        query: 'SEARCH_QUERY',
        filters: `date_timestamp > ${dateTimestamp}`,
      };

      await client.searchSingleIndex({ indexName: 'indexName', searchParams: searchParams });

      ```

      ```kotlin Kotlin theme={"system"}
      import com.algolia.client.api.SearchClient
      import com.algolia.client.configuration.*
      import com.algolia.client.extensions.*
      import com.algolia.client.model.search.*
      import com.algolia.client.transport.*
      import java.time.Instant

      suspend fun searchFuturePublishedBooks() {
        val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")

        val dateTimestamp = Instant.now().epochSecond
        val searchParams =
          SearchParamsObject(query = "SEARCH_QUERY", filters = "date_timestamp > $dateTimestamp")

        client.searchSingleIndex(indexName = "INDEX_NAME", searchParams = searchParams)
      }

      ```

      ```php PHP theme={"system"}
      <?php

      require __DIR__.'/../vendor/autoload.php';
      use Algolia\AlgoliaSearch\Api\SearchClient;
      use Algolia\AlgoliaSearch\Model\Search\SearchParamsObject;

      $client = SearchClient::create('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');

      $dateTimestamp = time();
      $searchParams = (new SearchParamsObject())
          ->setQuery('SEARCH_QUERY')
          ->setFilters('date_timestamp > '.$dateTimestamp)
      ;

      $client->searchSingleIndex(
          'INDEX_NAME',
          $searchParams,
      );

      ```

      ```python Python theme={"system"}
      import time

      from algoliasearch.search.client import SearchClientSync


      _client = SearchClientSync("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")


      date_timestamp = time.time()  # Get current timestamp
      search_params = {
          "query": "SEARCH_QUERY",
          "filters": f"date_timestamp > {date_timestamp}",
      }

      _client.search_single_index(
          index_name="INDEX_NAME",
          search_params=search_params,
      )

      ```

      ```ruby Ruby theme={"system"}
      import(time)

      require "algolia"

      client = Algolia::SearchClient.create("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")

      # Get current timestamp
      date_timestamp = Time.now.to_i
      search_params = Algolia::Search::SearchParamsObject.new(
        query: "SEARCH_QUERY",
        filters: "date_timestamp > #{date_timestamp}"
      )

      client.search_single_index("INDEX_NAME", search_params)

      ```

      ```scala Scala theme={"system"}
      import scala.concurrent.ExecutionContext.Implicits.global
      import scala.concurrent.Future
      import java.time.Instant

      import algoliasearch.api.SearchClient
      import algoliasearch.config.*
      import algoliasearch.extension.SearchClientExtensions
      import algoliasearch.search.SearchParamsObject

      def searchFuturePublishedBooks(): Future[Unit] = {
        val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")

        val dateTimestamp = Instant.now.getEpochSecond
        val searchParams = SearchParamsObject(
          query = Some("SEARCH_QUERY"),
          filters = Some(s"date_timestamp > $dateTimestamp")
        )

        client
          .searchSingleIndex(
            indexName = "INDEX_NAME",
            searchParams = Some(searchParams)
          )
          .map { response =>
            println(response)
          }
          .recover { case ex: Exception =>
            println(s"An error occurred: ${ex.getMessage}")
          }
      }

      ```

      ```swift Swift theme={"system"}
      import Foundation
      #if os(Linux) // For linux interop
          import FoundationNetworking
      #endif

      import AlgoliaCore
      import AlgoliaSearch

      func searchFuturePublishedBooks() async throws {
          let client = try SearchClient(appID: "ALGOLIA_APPLICATION_ID", apiKey: "ALGOLIA_API_KEY")

          let dateTimestamp = Int(Date().timeIntervalSince1970)
          let searchParams = SearchSearchParams.searchSearchParamsObject(
              SearchSearchParamsObject(query: "SEARCH_QUERY", filters: "date_timestamp > \(dateTimestamp)")
          )

          let response: SearchResponse<Hit> = try await client.searchSingleIndex(
              indexName: "INDEX_NAME",
              searchParams: searchParams
          )
          print(response)
      }

      ```
    </CodeGroup>
  </Step>
</Steps>

## Filter by array

[Example dataset](#example-dataset)

Some attributes, such as the genre of a book, are lists of values. One book can belong to multiple genres.
Hence, the genre attribute should be an array.

If you have a chain of bookstores with an accompanying ecommerce website, you may want to let users filter by book genre and store. To do this, the example dataset has two array attributes: `store` and `categories`.

Using this dataset, users could, for example, retrieve all books about politics in stock in The Corner Bookshop.

### Apply an array filter

Once you've set `categories` and `store` as [attributes for faceting](/doc/guides/managing-results/refine-results/filtering#define-filterable-attributes), apply string filters with the [`filters`](/doc/api-reference/api-parameters/filters) parameter in your [`search`](/doc/libraries/sdk/v1/methods/search) code:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(
      new SearchParamsObject
      {
        Query = "ben",
        Filters = "categories:politics AND store:Gibert Joseph Saint-Michel",
      }
    )
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      query: "ben",
      filters: "categories:politics AND store:Gibert Joseph Saint-Michel",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetQuery("ben").SetFilters("categories:politics AND store:Gibert Joseph Saint-Michel"))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex(
    "INDEX_NAME",
    new SearchParamsObject().setQuery("ben").setFilters("categories:politics AND store:Gibert Joseph Saint-Michel"),
    Hit.class
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: 'indexName',
    searchParams: { query: 'ben', filters: 'categories:politics AND store:Gibert Joseph Saint-Michel' },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams =
        SearchParamsObject(
          query = "ben",
          filters = "categories:politics AND store:Gibert Joseph Saint-Michel",
        ),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['query' => 'ben',
          'filters' => 'categories:politics AND store:Gibert Joseph Saint-Michel',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "query": "ben",
          "filters": "categories:politics AND store:Gibert Joseph Saint-Michel",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(
      query: "ben",
      filters: "categories:politics AND store:Gibert Joseph Saint-Michel"
    )
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          query = Some("ben"),
          filters = Some("categories:politics AND store:Gibert Joseph Saint-Michel")
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(
          query: "ben",
          filters: "categories:politics AND store:Gibert Joseph Saint-Michel"
      ))
  )
  ```
</CodeGroup>

## Filter by boolean

[Example dataset](#example-dataset)

Algolia lets you filter results by boolean attributes.

For example, you can use the `is_available` boolean attribute in the example dataset to exclude all records where `is_available` is `false`. To do this, first [declare `is_available` as an attribute for faceting](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting).

### Apply a boolean filter

If you want users to see only the available books, do the following:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(new SearchParamsObject { Filters = "is_available:true" })
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      filters: "is_available:true",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetFilters("is_available:true"))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex(
    "INDEX_NAME",
    new SearchParamsObject().setFilters("is_available:true"),
    Hit.class
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: 'indexName',
    searchParams: { filters: 'is_available:true' },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = SearchParamsObject(filters = "is_available:true"),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['filters' => 'is_available:true',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "filters": "is_available:true",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(filters: "is_available:true")
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          filters = Some("is_available:true")
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams
          .searchSearchParamsObject(SearchSearchParamsObject(filters: "is_available:true"))
  )
  ```
</CodeGroup>

Algolia considers boolean values as integers: `false` as `0` and `true` as `1`.
This means you can apply [numeric filters](#filter-by-numeric-value) for boolean attributes.
With the example dataset, `is_available=0` is the same as `is_available:false`.

<Note>
  If creating numeric or boolean filters, you don't need to declare the attribute as `attributesForFaceting`.
</Note>

## Filter by tags

[Example dataset](#example-dataset)

Sometimes, you may want to filter search results based on specific metadata, like a type or a category.

Using the example dataset, the accompanying online bookstore has fiction and non-fiction sections.
Depending on which section users are searching from, **you can provide a context-sensitive search experience**.
For example, a user goes to the website's non-fiction section, then starts searching for the biography of President Harry S. Truman.
If your search relevance is primarily based on popularity, by typing "harry", they might retrieve Harry Potter books first, which wouldn't make sense to them.

Instead, what you can do is **filter results based on what they most likely want to find**.
Algolia lets you add tags to your records with the reserved `_tags` attribute.

Using the example dataset, if users type "harry" with the search restricted to "non-fiction", it would retrieve  "Where the Buck Stops" because it has "non-fiction" in the `_tags` attribute and contains the word "harry" in the record.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(new SearchParamsObject { Query = "harry", Filters = "_tags:non-fiction" })
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      query: "harry",
      filters: "_tags:non-fiction",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetQuery("harry").SetFilters("_tags:non-fiction"))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex(
    "INDEX_NAME",
    new SearchParamsObject().setQuery("harry").setFilters("_tags:non-fiction"),
    Hit.class
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({
    indexName: 'indexName',
    searchParams: { query: 'harry', filters: '_tags:non-fiction' },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = SearchParamsObject(query = "harry", filters = "_tags:non-fiction"),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['query' => 'harry',
          'filters' => '_tags:non-fiction',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "query": "harry",
          "filters": "_tags:non-fiction",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(query: "harry", filters: "_tags:non-fiction")
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          query = Some("harry"),
          filters = Some("_tags:non-fiction")
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(
          query: "harry",
          filters: "_tags:non-fiction"
      ))
  )
  ```
</CodeGroup>

If you don't specify an attribute name, the filter is assumed to apply to the `_tags` attribute. For example, `fiction` translates into `_tags:fiction`.

You can also use [`tagFilters`](/doc/api-reference/api-parameters/tagFilters) to do the same thing.

### The difference between \_tags and custom attributes

It's important to consider the following when deciding whether to use the Algolia `_tags` attribute or a custom attribute for faceting:

* `_tags` is a [reserved attribute](/doc/guides/sending-and-managing-data/prepare-your-data/in-depth/what-is-in-a-record#reserved-attribute-names) which means it automatically works as a string filter without you having to set it as an attribute for faceting or use the `filterOnly` modifier.
* `_tags` isn't searchable by default.
* You can't use `_tags` for non-filtering purposes, such as displaying in search results or computing counts of records that match the filters.
* `_tags` can only contain strings.

In short, if you have several types of string filters or any non-string filters, creating a custom attribute is usually the way to go.

## Filter by null or missing attributes

Since Algolia **doesn't support filtering on `null` values or missing attributes**, what happens when your index contains an attribute that isn't present in all records?
For example, consider an online bookstore where people can buy and rate books from 0 to 5. Any record without the `rating` attribute is assumed to be unrated.
If you want users to search for both rated and unrated books in the same filter, you must modify your data.
To do this, you can take one of two approaches:

* [Use the `_tags` attribute](#create-a-tag)
* [Use a boolean attribute](#create-a-boolean-attribute).

### Create a tag

[Example dataset](#example-dataset)

At indexing time, you can add a tag value to indicate if a record is or isn't rated. In the example dataset, some records have a `rating` attribute and value, others have a null `rating`, and some don't have a `rating` attribute.

<Note>
  A `null` or nonexistent attribute is different from zero, which represents a book with the lowest rating.
</Note>

```jsonc JSON icon=braces theme={"system"}
[
  {
    // ...
    "rating": 5,
    "_tags": ["is_rated"]
  },
  {
    // ...
    "rating": null,
    "_tags": ["is_not_rated"]
  },
  {
    // ...
    "_tags": ["is_not_rated"]
  }
]
```

To search for records without the attribute or have a null value, you can now use [tags filtering](#filter-by-tags).

### Create a boolean attribute

At indexing time, you can add a boolean value to indicate if a record is or isn't rated:

```jsonc JSON icon=braces theme={"system"}
[
  {
    // ...
    "rating": 5,
    "is_rated": true
  },
  {
    // ...
    "rating": null,
    "is_rated": false
  },
  {
    // ...
    "is_rated": false
  }
]
```

To search for records without the attribute or have a null value, you can now use [boolean filtering](#filter-by-boolean).

## Filter by objectID

By default, Algolia sets a record's `objectID` attribute as a [filter-only facet](/doc/api-reference/api-parameters/attributesForFaceting#modifiers).
This means **you can use the [`filters`](/doc/api-reference/api-parameters/filters) parameter to filter on `objectID`**.
This is helpful when you want to include or exclude specific records in the current search.
For example, to exclude the record with `objectID` "1234", use the filter `NOT objectID:1234` in the [`filters`](/doc/api-reference/api-parameters/filters) parameter of your search.

## Example dataset

All the examples on this page use a bookstore index: `books`. The index has records that look like this:

```json JSON icon=braces theme={"system"}
[
  {
    "title": "Harry Potter and the Philosopher's Stone",
    "author": "J. K. Rowling",
    "publisher": "Bloomsbury",
    "price": 7.94,
    "publication_date": "1996-06-17",
    "date_timestamp": 866505600,
    "is_available": true,
    "rating": 5,
    "_tags": [
      "fiction",
      "is_rated"
    ],
    "popularity": 1000,
    "store": [
      "The Corner Bookshop",
      "Gibert Joseph Barbès",
      "Gibert Joseph Paris 13 - Grande Bibliothèque"
    ],
    "categories": [
      "fantasy",
      "science fiction",
      "children's literature"
    ]
  },
  {
    "title": "A Perfect Crime",
    "author": "Peter Abrahams",
    "publisher": "Penguin",
    "price": 7.94,
    "publication_date": "1998-09-16",
    "date_timestamp": 905904000,
    "is_available": true,
    "rating": null,
    "_tags": [
      "fiction",
      "is_not_rated"
    ],
    "popularity": 800,
    "store": [
      "The Corner Bookshop",
      "Gibert Joseph Barbès"
    ],
    "categories": [
      "thriller",
      "crime fiction"
    ]
  },
  {
    "title": "The World as It Is",
    "author": "Ben Rhodes",
    "publisher": "Penguin",
    "price": 9.54,
    "publication_date": "2018-06-05",
    "date_timestamp": 1528156800,
    "is_available": false,
    "_tags": [
      "non-fiction",
      "is_not_rated"
    ],
    "popularity": 900,
    "store": [
      "The Corner Bookshop"
    ],
    "categories": [
      "history",
      "politics"
    ]
  },
  {
    "title": "Yellowface",
    "author": "R.F. Kuang",
    "publisher": "The Borough Press",
    "price": 9.19,
    "publication_date": "2023-05-16",
    "date_timestamp": 1684108800,
    "is_available": true,
    "_tags": [
      "fiction",
      "is_not_rated"
    ],
    "popularity": 900,
    "store": [
      "The Corner Bookshop"
    ],
    "categories": [
      "dark humor",
      "satire"
    ]
  },
  {
    "title": "A Fighting Chance",
    "author": "Elizabeth Warren",
    "publisher": "Scribe",
    "price": 12.97,
    "publication_date": "2014-04-22",
    "date_timestamp": 1398124800,
    "is_available": false,
    "rating": 5,
    "_tags": [
      "non-fiction",
      "is_rated"
    ],
    "popularity": 800,
    "store": [
      "The Corner Bookshop"
    ],
    "categories": [
      "history",
      "politics"
    ]
  },
  {
    "title": "Where the Buck Stops",
    "author": "Harry S Truman",
    "publisher": "Warner Books",
    "price": 15.014,
    "publication_date": "1990-10-01",
    "date_timestamp": 654739200,
    "is_available": true,
    "_tags": [
      "non-fiction",
      "is_not_rated"
    ],
    "popularity": 800,
    "store": [
      "The Corner Bookshop"
    ],
    "categories": [
      "history",
      "politics",
      "biography"
    ]
  },
]
```
