Download the PHP package dbstudios/doctrine-query-document without Composer
On this page you can find all versions of the php package dbstudios/doctrine-query-document. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download dbstudios/doctrine-query-document
More information about dbstudios/doctrine-query-document
Files in dbstudios/doctrine-query-document
Package doctrine-query-document
Short Description Allows building Doctrine queries using MongoDB-style query documents
License GPL-3.0-or-later
Informations about the package doctrine-query-document
Installation
Basic Usage
Simply create a query builder, and (at minimum) add the from
and select
statements. These are required in order
for the query document to work. You may also add any other clauses (such as where
or orderBy
clauses) that you would
like to have in the resulting query. The query manager will append the query to the existing clauses in the query
builder.
Any values passed in the second argumemnt to apply()
will automatically be transformed to positional parameters and
will be set as a parameter on the query builder.
Traversing Relationships
Fields on related entities may be queried using dot notation, in the form relationshipField.field
. Imagine that your MyEntity
class is related to OtherEntity
through the field otherEntity
.
Traversing JSON Objects
MySQL 5.7 added support for the JSON type. For any fields whose type is JSON
, dot-notated fields will automatically be
extracted. Imagine that your MyEntity
class has a JSON field named attributes
, which looks like this.
You could query for it like so.
Field Mapping
In some cases, it may make sense to map shortened field names to fields on related entities. For example, assume the
otherEntity
field is a relation that contains a name
field.
Normally, the above example would fail, because MyEntity
does not have a otherEntityName
field. However, we can
alias the field like so.
This can also work in reverse, allowing you to query a field that appears to be on a related object (or, more usefully, an array of related objects). For example, assume MyEntity
has a one-to-many relationship with MyOtherEntity
. MyEntity
has a field named otherEntitiesLength
, which holds a count of the number of elements in the otherEntities
collection.
Field Projection
This library ships with a handy utility class that allows you to easily apply projections to result sets.
Projections can also be inverted by supplying false
as the value of each node in the constructor argument. If you want
to explicitly control the default matching behavior, you can also provide the optional $default
argument to the
constructor. Otherwise, default matching behavior will be inferred from the first element of the projection: allow if
the first element is false
(the projection is a deny-list), or deny if the first element is true
(the projection is
an allow-list).
There's also a static convenience method on Projection
that allows you to build the projection object from a flat
object of string paths, like so. Like the constructor, you can also pass a second $default
argument to explicitly set
the default matching behavior of the projection.
In the above example, the resulting Projection
object would be the same as the one in the original example. In some
cases, it may be more convenient to supply a flat map of paths, instead of a potentially deep array of paths (i.e. when
the projected fields are coming in from an API input).
You can also use the match-all operator "*" to control matching behavior for all fields in a group.
Projections can also differentiate between default or explicit allow/deny behavior. For example, consider the following projection.
This can be useful if you have a field that is expensive to compute or serialize, and you only want to include if the projection specifically calls for it to be included.
You can also directly inspect the underlying value that projections use to repesent results using the
Projection::query()
method, which returns an integer value that describes that result. Additionally, the
QueryResult::describe()
method can be used to get a plain-english representation of a result for debugging or logging
purposes.
A potential "gotcha" when working with projections relates to how the system determines what should and should not be considered "explicit" versus "implicit" when querying a field. Consider the following projection and query.
While foo
isn't given an allow or deny modifier (has a value of true
or false
), it does show up as a member of
our projection, and should be given the "explicit" flag. Additionally, in order to make queries against child nodes, it
is assumed to be "allowed," as it wouldn't make sense for a query to mark foo
as denied but still mark foo.bar
as
allowed: how can a child be allowed when its parent wasn't?
Custom Operators
You can add custom operator classes by implementing DaybreakStudios\DoctrineQueryDocument\OperatorInterface
, or by
extending DaybreakStudios\DoctrineQueryDocument\Operators\AbstractOperator
.
For example, you could implement the $eq
symbol using the following class.
In the example above, the getKey()
method should return the symbol used by the operator in a query document, without
the leading dollar sign. The process()
method will be called when the operator is used, and will receive the active
query document object, the raw field name that the operator is being called on, the value of the field, and the
Doctrine\ORM\Query\Expr\Composite
object that the resulting expression should be applied to.
In order to make changes to the query builder, you must use the DaybreakStudios\DoctrineQueryDocument\Expr
object
returned from QueryDocumentInterface::expr()
. Any method that takes a field name will automatically resolve the
dot-notated field name (such as relationshipField.field
) to an appropriately aliased field name. Values will
automatically be changed to posisitional parameters, and will be added to the query builder's parameter list.
You would then need to register your operator with your query manager, like so.
You may also pass an array of custom operators as the second argument to QueryDocument
's constructor.
Built-in Operators
By default, this packages comes with several operators that will be automatically registered with instances of
DaybreakStudios\DoctrineQueryDocument\QueryManager
. You may choose to skip registering built-in operators when
creating your query manager by passing false
as the third argument in the constructor.
Since most operators are based on MongoDB's query operators, please see Mongo's documentation for information on using the operators.
Operator | Accepted Argument(s) | Documentation |
---|---|---|
$and |
Array<Query> | Link |
$or |
Array<Query> | Link |
$gt |
Number | Link |
$gte |
Number | Link |
$lt |
Number | Link |
$lte |
Number | Link |
$eq |
Any | Link |
$neq |
Any | Link |
$in |
Array<Any> | Link |
$nin |
Array<Any> | Link |
$like |
String | A MySQL style LIKE string (Link) |
$nlike |
String | A negated MySQL LIKE string (Link) |
$exists |
Boolean | Link |
$size |
Number or Operators | Link [see below] |
$contains |
Scalar | see below |
$ncontains |
Scalar | see below |
Size Operator
The size operator accepts two different types of values. The first is the same type documented in the MongoDB docs: an integer to match exact equality to.
The second is a more complex form, allowing you to use any other comparison operator to match the collection size.
This operator utilizes Doctrine's SIZE
DQL function to retrieve the number of elements in a to-many association.
Contains Operator
The $contains
operator allows you to test if a collection or JSON array contains a given value.
When used on collection valued associations, Doctrine's MEMBER OF
syntax is used to test if the given value is
contained in the collection.
The $contains
operator can also be used on JSON fields, or on fields embedded within JSON fields.
Not Contains Operator
This is the negated form of the $contains
operator. Refer to the documentation for $contains
for more info.