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:
| Operator | Description | Example |
|---|---|---|
eq | Equals (case-sensitive) | ?where__status__eq=published |
ieq | Equals (case-insensitive) | ?where__status__ieq=Published |
gt, gte | Greater than (or equal to) | ?where__rating__gte=4.0 |
lt, lte | Less than (or equal to) | ?where__price__lt=100 |
in | Value is within a comma-separated list | ?where__category__in=tech,science |
iin | Value is within a case-insensitive list | ?where__category__iin=Tech,SCIENCE |
between | Value is within an inclusive range | ?where__price__between=50,200 |
contains | Field contains a substring (case-sensitive) | ?where__title__contains=API |
icontains | Field contains a substring (case-insensitive) | ?where__title__icontains=api |
startswith | Field starts with a prefix | ?where__slug__startswith=intro- |
endswith | Field ends with a suffix | ?where__email__endswith=@company.com |
includes | Array field contains a specific value | ?where__tags__includes=ai |
exists | Field has any non-null value | ?where__summary__exists=true |
null | Field 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.
Full-Text Search: Finding Keywords and Phrases
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:
You can only use one mode (find_text or find_phrase) per request. They cannot be combined.
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_atand_sys.updated_at. - Localization: Sorting on localized fields will respect the
search_localeparameter, 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
nextURL 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
previousURL 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
Collectionfolders (notComposite). - Reference Fields: Join fields must be of
referencetype in your schema.
Next Steps
- Understanding Semantic Search — Deep dive into how vector search works
- Multilingual Semantic Search — Cross-language search strategies
- List Resources API — GET endpoint reference
- Search API — POST endpoint reference with full schema