Filtering
Narrow results by metadata, dates, and identifiers.
Operators
| Operator | Description | Example value |
|---|---|---|
eq | Equals | "research" |
ne | Not equals | "deleted" |
in | Matches any in list | ["tech", "science"] |
not_in | Excludes values in list | ["spam", "junk"] |
gt | Greater than | 2020 |
gte | Greater than or equal | 2020 |
lt | Less than | 2025 |
lte | Less than or equal | 2025 |
between | Range (inclusive) | [2020, 2025] |
Simple format
Key-value pairs where each key is a metadata field name. Supports exact match, list membership, range operators, and negation.
Exact match
{
"filters": {
"journal": "Nature"
}
}Range
{
"filters": {
"publication_date": { "gte": "2020-01-01", "lte": "2025-12-31" }
}
}Any-of list
Pass an array to match any value in the list (equivalent to in).
{
"filters": {
"issn": ["1664-302X", "1932-6203"]
}
}Negation
{
"filters": {
"publisher": { "not": "Elsevier" }
}
}Structured DSL
Use boolean combinators (and, or, not) with explicit field conditions for complex filtering logic. Supports arbitrary nesting.
Basic AND condition
{
"filters": {
"and": [
{ "field": "publication_date", "gte": "2020-01-01" },
{ "field": "publisher", "eq": "SAGE Publications" }
]
}
}OR condition
{
"filters": {
"or": [
{ "field": "publisher", "eq": "tech" },
{ "field": "publisher", "eq": "science" }
]
}
}Nested combinators
Combinators can be nested to build complex expressions. This example matches documents from 2020-2025 that are either in the tech/science categories or have "published" status.
{
"filters": {
"and": [
{ "field": "publication_date", "gte": "2020-01-01" },
{ "field": "publication_date", "lte": "2025-12-31" },
{
"or": [
{ "field": "issn", "in": ["1664-302X", "1932-6203"] },
{ "field": "publisher", "eq": "SAGE Publications" }
]
}
]
}
}NOT combinator
Use not to exclude results matching a condition. Like and and or, it takes an array of conditions — passing a bare object is a parse error.
{
"filters": {
"and": [
{ "field": "publisher", "eq": "SAGE Publications" },
{
"not": [
{ "field": "issn", "eq": "1932-6203" }
]
}
]
}
}Filtering by journal and article identity
issn and doi are both indexed. Prefer issn over journal when you mean a specific journal: the same journal appears in the corpus under several title spellings ("PLOS ONE", "PLOS One", "PLoS ONE"), while its ISSN does not change.
ISSN accepts hyphenated or bare, upper- or lower-case check character — all four forms select the same journal:
{ "filters": { "issn": "1664-302X" } }"1664-302X", "1664-302x", "1664302X" and "1664302x" are equivalent.
DOIs are matched case-insensitively, and a resolver prefix is optional:
{ "filters": { "doi": "10.1345/aph.1g425" } }"10.1345/APH.1G425", "https://doi.org/10.1345/aph.1g425" and "doi:10.1345/aph.1g425" are equivalent.
Exclusion uses the operators you already have — ne, not_in and not. There is no separate exclusion syntax. Documents carrying no ISSN at all are not removed by an issn exclusion.
{
"filters": {
"and": [
{ "field": "issn", "not_in": ["1932-6203", "2045-2322"] }
]
}
}Journal metrics
Filter by a journal-level citation metric. These fields accept range operators only (gt, gte, lt, lte, between) and are resolved server-side into the matching ISSNs, so they cost nothing extra at search time.
Available: journal_metric.2yr_mean_citedness, journal_metric.h_index, journal_metric.i10_index.
This is not an impact factor. The value is OpenAlex's 2-year mean citedness, published under CC0. The Journal Impact Factor is Clarivate's proprietary metric, computed over the Web of Science corpus with a different citation window; the two are not interchangeable and the numbers will not agree.
A journal the metric provider has no value for is absent from the result, not scored zero — so a lt threshold does not sweep up unrated journals.
{ "filters": { "journal_metric.2yr_mean_citedness": { "gte": 5.0 } } }{ "filters": { "journal_metric.2yr_mean_citedness": { "lt": 2.0 } } }Exclude by metric:
{
"filters": {
"not": [
{ "field": "journal_metric.2yr_mean_citedness", "gte": 20 }
]
}
}The response reports what each threshold expanded to, so the selection is inspectable. The expansion is capped: a threshold matching more ISSNs than the cap returns an error rather than a truncated list, because a partial list would return confidently wrong results.
{
"results": [ ... ],
"journalMetricExpansions": [
{
"field": "journal_metric.2yr_mean_citedness",
"condition": "gte 5.0",
"matchedJournals": 212,
"issnCount": 383,
"sampleIssns": ["0028-0836", "1476-4687", "0027-8424"]
}
]
}Filtering on other fields
Indexed on every collection: doc_id, journal, publisher, keywords, publication_date, doi, issn, article_type and section.
Additionally indexed on editorial collections only: topic, url and medical_board_approved.
Filtering on any other payload field still works and is not rejected — but it is matched by scanning rather than by index, which can be slow or time out on large collections. When that happens the response carries a warning:
{
"results": [ ... ],
"filterWarnings": [
{
"code": "unindexed_filter_field",
"field": "article_type",
"message": "Filter field 'article_type' has no payload index, so it is matched by scanning and may be slow or time out on large collections."
}
]
}Date filtering
ISO date strings (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS) are automatically detected and used for datetime range queries. No special syntax is needed -- just pass the date string as a value.
Date range with gte/lte
{
"filters": {
"and": [
{ "field": "publication_date", "gte": "2024-01-01" },
{ "field": "publication_date", "lte": "2024-12-31" }
]
}
}Date range with between
{
"filters": {
"field": "publication_date",
"between": ["2024-01-01", "2024-12-31"]
}
}The filters parameter is part of the Search API request body. See the full endpoint reference for more details.