Query builders
Server-side database query builders in Apostrophe help developer refine database document queries or refine the query results in some way. The sections below organize core query builders by the relevant document types.
See the database querying guide for general information about using query builders.
Builders for all doc types
The following query builders apply to all Apostrophe doc types.
addUrls()
query.addUrls(false)
Default value: true
The addUrls
builder controls whether to invoke the addUrls
method for doc types included in the query results. If set to false
, addUrls
methods are not invoked.
This effectively controls whether the query results should include a _url
property on individual documents, when available. _url
is a dynamic property (not stored in the database) containing the document's unique URL. Not all documents have a unique URL.
Only piece type modules have an addUrls
method in Apostrophe core. By default, page documents always include the _url
property.
and()
query.and({ price: { $gte: 0 } })
The and
builder adds additional required criteria to the query. The value should be a MongoDB criteria object (as you would use in the find()
operation). This is the main way to add criteria to a database query. It can be used multiple times to continue adding criteria.
Since this is the main way additional criteria get merged, this method performs a few transformations of the query to make it more readable when APOS_LOG_ALL_QUERIES=1
is in the environment.
archived()
query.archived(false)
The archived
builder tells the query whether or not to include archived documents in the results. It takes boolean value, undefined
, or null
(empty).
If the builder value is false
, undefined
or this method is never called, the query only returns docs that are not in the archive. This is the default behavior for document queries.
If the value is true
the query returns only docs in the archive. Note that permissions would still prevent a typical site visitor from obtaining any results, but an editor might.
If the value is null
(not undefined
), the query returns docs regardless of archived status.
areas()
query.areas(false)
query.areas([ 'thumbnail' ])
Default value: true
The areas
builder controls whether to call the load
methods of widget type managers for widgets in areas. load
methods are used to do things such as populating relationships in widgets and other asynchronous actions when areas are loaded.
The default value is true
. Pass false
to prevent the extra processing for a particular query. This is helpful to make queries faster when detailed area data is not needed.
The value can also be an array containing strings representing area field names or dot paths to nested area fields. For example, with .areas([ 'thumbnail' ])
you could load only the 'thumbnail'
area for all pages matching the query.
attachments()
query.attachments(true)
Default value: false
Passing true
to the attachments
builder will annotate all attachment fields in the returned documents with URLs and other metadata (primarily for images). This uses the the apos.attachment.all
method with the annotate: true
option.
autocomplete()
query.autocomplete('tree')
The autocomplete
builder operates as a sort of fuzzy search for documents. It accepts a string and uses document search text properties to find matches. The string can contain multiple words, but only the final word may be a partial string to find non-exact results. So "tree" will find results with "treehouse," but "treehouses" will not find "treehouse" (it is not meant as an advanced search tool, but can help find similar results).
This will only find partial matches in high-priority properties such as the title
, or any string, select or checkbox field in the schema of the document.
criteria()
query.criteria({ category: { $in: ['animals', 'vegetables'] } })
Default value: {}
The criteria
builder sets the base MongoDB query criteria, discarding criteria previously added using this method or the and
builder. The and
builder is usually better for most cases since it is not destructive. The default value of this builder is an empty object. As with the and
builder, the criteria format would match that used in the MongoDB find
operation.
defaultSort()
query.defaultSort({ updatedAt: 1 })
The defaultSort
changes the default value for the sort
query builder. The argument is the same as for the sort
query builder: an object like { updatedAt: 1 }
, including a field name and 1
for ascending or -1
for descending. See the MongoDB sort
method documentation for other options. false
can be passed as an option as well to clear the default sort.
It is distinct from the sort
builder to distinguish between cases where a default sort should be ignored (for instance, the search
query builder is present) and cases where a sort is explicitly requested by the user.
In most custom uses the sort
builder will likely be a more common option.
_ids()
query._ids([
'ckwxzxdtr000t4v3rivysoari:en:published',
'ckwxzxdvc001b4v3rhxvxqgg1:en:published'
])
The _ids
builder causes the query to return only the document with matching _id
properties and to return them in that order, assuming the documents with the specified IDs exist. All documents are fetched in the locale and mode of the request regardless of the locale suffix of the values. If no locale can be determined via query parameters, the locale is inferred from the first _id in the set.
The query builder can also be called with a string, which is treated as a single document ID.
limit()
query.limit(10)
The limit
query builder accepts an integer and limits the number of document results. It returns the first matching documents up to the set limit after taking the skip
builder into account.
locale()
query.locale('es:published')
Default value: false
A valid locale identifier passed to the locale
builder will tell the query to return results only belonging to that locale, including the mode (draft
or published
) after a :
character. Documents that match the query and have no locale (because their doc type is not localized) are also included in the results. Specifically passing false
(the default value) will use the locale and mode on the req
request object.
log()
query.log(true)
Default value: false
Setting the builder .log(true)
on a query will log the the query criteria on the server (or the terminal when working on a local machine).
next()
query.next({
_id: 'cgwxzcdvc501b4v3ghxvxqgg1:en:published',
...
})
Default value: false
Passing a document object to the next
builder returns the document that follows it in the current sort order. The document object argument needs to at least include the properties used by the current sort as well as the _id
. The _id
is used as a tiebreaker to avoid loops.
page()
query.page(5)
Default value: 1
The page
builder is used to request a particular "page," or set, of results when the perPage
builder is also used. Page numbers start with 1
(there is no page zero).
pageUrl()
query.pageUrl(false)
Default value: true
The pageUrl
query builder is set to true
by default and controls whether to add the ._url
property to page documents in the query results. The builder can be set to false
to disable the ._url
property on a particular query.
The ._url
property will include a site prefix if applicable and is always better to use than the document's slug
for a URL.
permission()
query.permission('edit')
The permission
builder is used to restrict returned documents based on the action name passed as an argument. Only documents on which the req
object can take the named action are returned. For example, using .permission('edit')
on the query will only return documents that the requesting user (via req
) can edit.
Valid action arguments include:
'view'
: Thereq
has permission to view the documents. This is the default.'edit'
: Thereq
has permission to edit the documents.'publish'
: Thereq
has permission to publish the documents.false
: Bypass any permission checks. This returns everything regardless of permission level. Use this with caution.
In all cases, all of the returned docs are marked with _edit: true
properties if the user associated with the request is allowed to edit the document and _published: true
if the user is allowed to publish it. This is useful if you are fetching docs for viewing but also want to know which ones can be edited.
perPage()
query.perPage(20)
Default value: undefined
Using the perPage
builder returns documents in sets of the number passed as an argument. This helps return documents in managable numbers and paginate the results, using the page
query builder to get a specific set of results. This is usually easier than using skip
and limit
directly.
After the query completes, with await query.toArray()
for instance, query.get('totalPages')
will return the total number of pages.
previous()
query.previous({
_id: 'cgwxzcdvc501b4v3ghxvxqgg1:en:published',
...
})
Default value: false
Passing a document object to the previous
builder returns the document that precedes it in the current sort order. The document object argument needs to at least include the properties used by the current sort as well as the _id
. The _id
is used as a tiebreaker to avoid loops.
project()
query.project({
title: 1,
category: 1,
updatedAt: 1
})
The project
builders sets the MongoDB projection, specifying the document properties to included in the returned documents. The argument should be an object with properties of desired field names set to 1
to include those fields. Negative projections (category: 0
) are currently not supported.
In addition to database properties, Apostrophe provides two dynamic properties that can be included in the project
builder object:
_url: 1
will include all properties required to generate an accurate_url
property for each returned document._relationshipName: 1
will add the properties required to permit a field of typerelationship
to be loaded, even though the related documents are not stored redundantly in the database. In this example, the name of the field is_relationshipName
._articles: 1
could do the same for a relationship toarticle
pieces.
relationships()
query.relationships(false)
query.relationships(['_author'])
Default value: true
By default, relationship data are fetched for queried documents. The relationships
builder can prevent or limit this.
Pass false
to the builder to not retrieve any relationship data. You may also pass an array of relationship names, which will fetch only those relationships and those intermediate to them (using dot notation).
sort()
query.sort({ updatedAt: -1, title: 1 })
The sort
builder sets the sorting order for returned documents. If not set, the default is used, from the defaultSort
builder or module configuration. The sort argument is an object like { updatedAt: 1 }
, including a field name and 1
for ascending or -1
for descending. See the MongoDB sort
method documentation for other options.
false
can be passed as an option to use no sort definition at all. This can be helpful when using MongoDB operators like $near
, which already sort.
If this method is never called or the argument is undefined
, a case-insensitive sort on the title is normally the default. If search()
has been called, then a sort by search result quality is the default.
If the query sorts on a field that is defined in a doc type's schema with the sortify: true
option, then this query builder will automatically substitute a "sortified" version of the field: case-insensitive and ignoring extra whitespace and punctuation. This provides a more natural sort than MongoDB normally does.
skip()
query.skip(10)
The skip
builder accepts a number as an argument, then skips that number of documents in a query's results. This affects toArray
and toObject
. It does not affect toDistinct
or toMongo
.
search()
query.search('tree')
The search
builder limits results to those matching the string passed as an argument. Search is implemented using MongoDB's $text
operator and a full text index. The search
builder does not support partial matches. For that, see the autocomplete
builder.
If this query builder is set, the sort
query builder will default to sorting by search quality. This is important because the worst of the full-text search matches will be of very poor quality.
type()
query.type('product')
The type
builder can be used to limit a query to only one particular doc type. Pass the doc type name (string) as an argument.
Generally you don't want to call this method directly. It will be better to use a doc type module's find
method, which limits to that type automatically. You can also include the doc type name as the type
criteria in a generic find()
method's arguments.
withPublished()
query.withPublished(true)
If the withPublished
builder is set to true
, then each document in the results will include a _publishedDoc
property. That property will be set to the published version of that document. This is really only useful when querying for draft documents.
Page document query builders
The following query builders are only available on query created with the page module's apos.page.find
method and page REST API routes.
ancestors()
query.ancestors(true)
query.ancestors({ children: true })
Default value: false
Setting the ancestors
builder to true
retrieves the array of "ancestors" for each returned page and assigns them to the _ancestors
property. Page ancestors are those that precede a given page in the page tree hierarchy. The home page is _ancestors[0]
. A returned page is not included in its own _ancestors
array.
If the builder's argument is an object, the builder does all of the above, and also calls the query builders present in the object on the query that fetches the ancestors. For example, you can pass { children: true }
to fetch the children of each ancestor as the _children
property of each ancestor, or pass { children: { depth: 2 } }
to get two layers of child pages.
ancestors
also has its own depth
option, but it might not do what you think. If the depth
option is present as a top-level property of the ancestors
builder argument, then only that number of ancestors are retrieved, counting backwards from the immediate parent of each page. So { depth: 2 }
retrieves only the two closest ancestors.
children()
query.children(true)
query.children({ depth: 1 })
Default value: false
The children
builder is used to include the "children" of returned pages in an array on a _children
property. If children(true)
is called, it will return all children of a given page. If the argument is an object, it may have a depth
property to fetch a specific number of child layers. Any other properties are passed on as builders for the query that fetches the children.
isPage()
query.isPage(true)
Default value: true
Passing true
to the isPage
builder ensures that results will only include documents that are pages.
orphan()
query.orphan(true)
The orphan
builder is used to return documents based on their "orphan" status. Orphans are pages that are not returned by the default behavior of the children
query builder and thus are left out of standard navigation.
If flag is true
, return only orphan docs. If flag is false
, return only docs that are not orphans. If .orphan(null)
or undefined
is called, or this method is never called, return docs regardless of orphan status.
Image document query builders
The following query builders are only available on query created with the image module's apos.image.find
method and piece REST API routes when dealing with the @apostrophecms/image
piece type.
minSize()
query.minSize([ 600, 800 ])
The minSize
query builder can be used to set a minimum size for returned image documents. The argument should be an array with two values: the image width and the image height, in that order. The sizes are measured in pixels.