FB4D Reference IStructuredQuery - SchneiderInfosystems/FB4D GitHub Wiki
Interface IStructuredQuery
This interface allows creating a query for retrieve data from the Firestore Database. The interface will be created by the class function TStructuredQuery.CreateForCollection
in the unit FB4D.Firestore.
This interface supports a fluent interface design. That is why the methods QueryForFieldFilter
and QueryForCompositeFilter
can be called in cascades because they return the caller interface for adding the next query.
The following sample illustrates how simple a query can build for retrieve all nodes of MyCollection
that contains a sub-node MyValue
which fits the content in the string variable SearchValue
.
var
Database: IFirestoreDatabase;
begin
Database.RunQuery(
TStructuredQuery.CreateForCollection('MyCollection').QueryForFieldFilter(
TQueryFilter.StringFieldFilter('MyAttribute', woEqual, SearchValue:string)),
OnDocuments, OnRequestError);
The above query fits the following demo data. For a SearchValue
red
the document with the ID 2MPuHwXjoMUuVeU9f34e will be returned:
The method QueryForCompositeFilter
allows combining several IQueryFilter by applying the logical And operator.
The following example shows a simple composite query for the search term: (MyAttribute='red') and (MyVal <= 5.0)
Database.RunQuery(
TStructuredQuery.CreateForCollection('MyCollection').QueryForCompositeFilter(
coAnd,
[TQueryFilter.StringFieldFilter('MyAttribute', woEqual, 'red'),
TQueryFilter.BooleanFieldFilter('MyVal', woLessThan, 5.0)]),
OnDocuments, OnRequestError)
If you do not need the entire document, you can use IStructuredQuery.Select(FieldRefs: TRequestResourceParam)
and pass only a list of field names. For better code, there is also a class method TStructuredQuery.CreateForSelect
implemented that creates an IStructuredQuery and call the method select as first:
Database.RunQuery(
TStructuredQuery.CreateForSelect(['MyField1', 'MyField2', 'MyField3']).
Collection('MyCollection'));
According to the SQL select statement, there is an order-by method:
function IStructuredQuery.OrderBy(const FieldRef: string;
Direction: TOrderDirection): IStructuredQuery;
Whereas TOrderDirection
has the following options odAscending
or odDescending
.
When you have more than one sort order level, call this OrderBy
level by level with the field name and its sort order direction.
Because the Delphi class interface uses automatic reference counting ARC you do not need manually to get free the created instances of IQueryFilter and IStructuredQuery. This enables the efficient fluent interface design, which after having created the structured query by CreateForSelect
, loops it through several filter functions such as Collection
followed by OrderBy
.
Database.RunQuery(
TStructuredQuery.CreateForSelect(['MyField1', 'MyField2', 'MyField3']).
Collection('MyCollection').
OrderBy('MyField1', odDescending));
In order to fetch only a subset of the resulting document set the method Limit
allows passing a maximal number of documents and the method Offset
let to define the first returned document.
function IStructuredQuery.Limit(limit: integer): IStructuredQuery;
function IStructuredQuery.Offset(offset: integer): IStructuredQuery;
Additionally, the Firestore offers a second approach to do the same thing: With StartAt
and EndAt
you can pass a start document and an end document in the parameter Cursor.
function IStructuredQuery.StartAt(Cursor: IFirestoreDocument; Before: boolean): IStructuredQuery;
function IStructuredQuery.EndAt(Cursor: IFirestoreDocument; Before: boolean): IStructuredQuery;
The parameter Before
defines if the position is just before or just after the given cursor, relative to the sort order defined by the query.