Guide to Querying in FoxNose

FoxNose provides a powerful, unified query system through the Flux API. Instead of learning different syntaxes for different databases, you can find your content using three complementary methods—often in a single request.

This guide provides a high-level overview of the different ways to query your data.

  • Structured Filtering: For finding content based on exact field values, ranges, and complex logical conditions (AND/OR/NOT). Ideal for precise, targeted queries.
  • Full-Text Search: For classic keyword and phrase-based search with typo tolerance and relevance ranking.
  • Semantic Search: For understanding user intent and finding conceptually related content, even if keywords don't match.

Understanding how to combine these methods is the key to building a truly powerful search experience.


Structured Filtering

When you need to find content based on exact criteria, structured filtering is your tool. It allows you to query specific field values, ranges, and build complex logical conditions to pinpoint the exact data you need.

Basic Syntax (GET Requests)

For simple filters and direct querying, you can use query parameters in GET requests:

?where__{field}__{operator}={value}

You can combine multiple where__ parameters, and they will be joined with AND logic.

Operators: Tailor Your Queries

FoxNose provides a comprehensive set of operators to give you granular control over your filtering:

OperatorDescriptionExample
eqEquals (case-sensitive)?where__status__eq=published
ieqEquals (case-insensitive)?where__status__ieq=Published
gt, gteGreater than (or equal to)?where__rating__gte=4.0
lt, lteLess than (or equal to)?where__price__lt=100
inValue is within a comma-separated list?where__category__in=tech,science
iinValue is within a case-insensitive list?where__category__iin=Tech,SCIENCE
betweenValue is within an inclusive range?where__price__between=50,200
containsField contains a substring (case-sensitive)?where__title__contains=API
icontainsField contains a substring (case-insensitive)?where__title__icontains=api
startswithField starts with a prefix?where__slug__startswith=intro-
endswithField ends with a suffix?where__email__endswith=@company.com
includesArray field contains a specific value?where__tags__includes=ai
existsField has any non-null value?where__summary__exists=true
nullField has a null value?where__deleted_at__null=true

Negation: Finding What's Not There

Prefix any operator with not_ to reverse its logic:

  • ?where__status__not_in=archived,deleted (Articles NOT in archived or deleted status)
  • ?where__description__not_null=true (Products that are NOT null)

Complex Queries: AND, OR, and Nested Logic (POST Requests)

For advanced scenarios requiring OR logic, nested conditions, or combining multiple complex filters, use the POST /_search endpoint. This gives you full flexibility to build intricate query structures:

POST /_search
{
  "where": {
    "all_of": [
      { "status__eq": "published" },
      {
        "any_of": [
          { "category__in": ["tech", "science"] },
          { "tags__includes": "featured" }
        ]
      }
    ]
  }
}

This query finds published articles that are either in tech/science categories OR tagged as featured.


When you need to find content based on specific words or phrases, full-text search is your tool. It's ideal for building user-facing search bars where you expect keyword-based queries with typo tolerance.

FoxNose offers two modes for full-text search:

1. Text Search (find_text__*)

This is your general-purpose keyword search. It finds resources containing your search terms with typo tolerance and relevance ranking. It is typically used via query parameters in GET requests for simple queries, but can also be part of a POST request for complex search payloads.

# Search title and summary for "machine learning" with a fuzziness of 0.8 (GET Request)
?find_text__query=machine%20learning&find_text__fields=title,summary&find_text__threshold=0.8
  • find_text__query: The search terms.
  • find_text__fields: A comma-separated list of fields to search. Defaults to all searchable fields if omitted.
  • find_text__threshold: The fuzziness for typo tolerance (a float between 0.0 for very fuzzy and 1.0 for exact).

2. Phrase Search (find_phrase__*)

Use this when you need to find an exact phrase in a specific order. Like Text Search, it can be used in both GET (query parameters) and POST (payload) requests.

# Find the exact phrase "artificial intelligence" in the title field (GET Request)
?find_phrase__query=artificial%20intelligence&find_phrase__fields=title
  • find_phrase__query: The exact phrase to search for.
  • find_phrase__fields: The fields to search within.

Combining with Structured Filters

Both full-text search modes can be combined with the structured filters described above, allowing you to build powerful, precise queries. For complex combinations, including full-text search, it's often more practical to use the /_search endpoint.

# Search for "kubernetes" in published tech articles (GET Request example)
?find_text__query=kubernetes&where__status__eq=published&where__category__eq=tech
POST /_search
{
  "find_text": {
    "query": "kubernetes",
    "fields": ["title", "summary"]
  },
  "where": {
    "all_of": [
      { "status__eq": "published" },
      { "category__eq": "tech" }
    ]
  }
}

Sorting Results

By default, results are returned in a default order, but you can control the final sort order using the sort parameter.

  • Syntax: Use a comma-separated list of field names (e.g., ?sort=title,_sys.created_at).
  • Direction: Prefix a field name with a hyphen (-) to sort in descending order.
  • System Fields: You can sort by any field in your schema, as well as system fields like _sys.created_at and _sys.updated_at.
  • Localization: Sorting on localized fields will respect the search_locale parameter, ensuring correct alphabetical order for that language.

Example: Newest first, then by title

?sort=-_sys.created_at,title

Pagination

When dealing with a large number of search results, FoxNose uses cursor-based pagination to provide efficient and consistent navigation. This method ensures that your results remain stable across subsequent page requests, even if new data is added or removed.

How Cursor-Based Pagination Works

When you make a query, the Flux API response includes a next URL (if more results are available). This URL contains a cursor, which is an opaque token representing the state of your query.

{
  "limit": 50,
  "next": "https://.../your-folder/_search?limit=50&cursor=eyJjcmVh...",
  "previous": null,
  "results": [...]
}

Navigating Pages

  • First Page: Make your initial query, optionally specifying a limit.
    GET /articles?limit=50
    
  • Next Page: Simply follow the next URL provided in the API response. The cursor automatically preserves all your original filters and search state.
    GET /articles?limit=50&cursor=eyJjcmVh...
    
  • Previous Page: Similarly, follow the previous URL for backward navigation.

This approach ensures a smooth and reliable experience when fetching large datasets for your applications.

Joining with Filters

You can apply filters to the joined content. For example, to find published articles by authors from the US:

POST /articles/_search
{
  "join": {
    "as": {
      "author_details": "authors"
    },
    "relations": [
      {
        "source": "$",
        "target": "author_details",
        "relation_type": "inner",
        "source_field": "author"
      }
    ]
  },
  "where": {
    "$": {
      "all_of": [{"status__eq": "published"}]
    },
    "author_details": {
      "all_of": [{"country__eq": "US"}]
    }
  }
}

Here, we use the filter for the primary articles folder and the author_details alias to filter the joined authors folder.

Important Considerations for Joins

  • Maximum Joins: You can join up to 3 additional collection folders in a single query.
  • Collection Folders Only: Joins are currently supported only for Collection folders (not Composite).
  • Reference Fields: Join fields must be of reference type in your schema.

Next Steps

Was this page helpful?