Custom field query
The custom_field_query filter lets you search documents by custom field values using a structured boolean expression. Paperless-ngx parses the expression serverside - pypaperless provides a small builder so you never have to construct the JSON by hand.
Basic usage
Build an expression and pass str(q) to the custom_field_query kwarg of documents.filter():
from pypaperless.builders import CustomFieldQuery as Q
q = Q("Status", "exact", "open")
async with paperless.documents.filter(custom_field_query=str(q)) as docs:
async for doc in docs:
print(doc.title)
Combining expressions
Use &, | and ~ to build boolean queries. Chained & and | are automatically flattened:
q = (
Q("Status", "exact", "open")
& Q("Amount", "gte", 100)
& ~Q("Archived", "exact", True)
)
# Serialises to:
# ["AND", [["Status","exact","open"], ["Amount","gte",100], ["NOT",["Archived","exact",true]]]]
OR across multiple categories:
Referencing a field
field can be either the integer ID or the name string:
Supported operators
The valid operators depend on the field's data type:
| Applies to | Operators |
|---|---|
| All types | exact in isnull exists |
STRING LONGTEXT URL MONETARY |
icontains istartswith iendswith |
INTEGER FLOAT MONETARY DATE |
gt gte lt lte range |
DOCUMENT_LINK |
contains |
DATE (component) |
year__exact month__exact day__exact etc. |
exists vs isnull
exists is the idiomatic way to check field presence:
Q("Due Date", "exists", True) # document has the field
Q("Due Date", "exists", False) # document does not have the field
in and range
Pass a list as the value:
Date components
Using build()
str(q) is shorthand for json.dumps(q.build()). Call build() directly if you need the raw Python structure:
q = Q("Amount", "gte", 50) & Q("Status", "exact", "open")
print(q.build())
# ["AND", [["Amount", "gte", 50], ["Status", "exact", "open"]]]
print(str(q))
# '["AND", [["Amount", "gte", 50], ["Status", "exact", "open"]]]'
Server-side limits
Paperless-ngx enforces:
- Maximum nesting depth: 10
- Maximum number of atoms: 20
Exceeding these limits returns a HTTP 400 validation error.
The full filter specification is in the Paperless-ngx API reference.