SQL++ for Mobile
Description - How to use SQL++ Query Strings to build effective queries with Couchbase Lite for React Native
Related Content - Live Queries | Indexes
|
N1QL is Couchbase’s implementation of the developing SQL++ standard. As such the terms N1QL and SQL++ are used interchangeably in all Couchbase documentation unless explicitly stated otherwise. |
Introduction
Developers using Couchbase Lite for React Native can provide SQL++ query strings using the SQL++ Query API. This API uses query statements of the form shown in Example 1. The structure and semantics of the query format are based on that of Couchbase Server’s SQL++ query language - see SQL++ Reference Guide and SQL++ Data Model.
Running
Use Database.createQuery to define a query through an SQL++ string. Then run the query using the Query.execute() method.
Example 1. Running a SQL++ Query
const query = database.createQuery('SELECT META().id AS thisId FROM inventory.hotel WHERE city="Medway"');
const resultSet = await query.execute();
Query Format
The API uses query statements of the form shown in Example 2.
Example 2. Query Format
SELECT ____
FROM ____
JOIN ____
WHERE ____
GROUP BY ____
ORDER BY ____
LIMIT ____
OFFSET ____
Query Components
-
The
SELECTclause specifies the data to be returned in the result set. -
The
FROMclause specifies the collection to query the documents from. -
The
JOINclause specifies the criteria for joining multiple documents. -
The
WHEREclause specifies the query criteria. TheSELECTed properties of documents matching this criteria will be returned in the result set. -
The
GROUP BYclause specifies the criteria used to group returned items in the result set. -
The
ORDER BYclause specifies the criteria used to order the items in the result set. -
The
LIMITclause specifies the maximum number of results to be returned. -
The
OFFSETclause specifies the number of results to be skipped before starting to return results.
|
We recommend working through the SQL++ Tutorials as a good way to build your SQL++ skills. |
SELECT Clause
Arguments
-
The select clause begins with the
SELECTkeyword.-
The optional
ALLargument is used to specify that the query should returnALLresults (the default). -
The optional
DISTINCTargument is used to specify that the query should return distinct results.
-
-
selectResultsis a list of columns projected in the query result. Each column is an expression which could be a property expression or any expression or function. You can use the*expression, to select all columns. -
Use the optional
ASargument to provides an alias for a column. Each column can be aliased by putting the alias name after the column name.
SELECT Wildcard
When using the * expression, the column name is one of:
* The alias name, if one was specified. * The data source name(or its alias if provided) as specified in the [FROM clause](https://cbl-dart.dev/queries/sqlplusplus-mobile/#from-clause).
This behavior is inline with that of SQL++ for Server - see example in Table 1.
Example
Example 4. SELECT Examples
SELECT * ...;
SELECT user.* AS data ...;
SELECT name fullName ...;
SELECT user.name ...;
SELECT DISTINCT address.city ...;
-
Use the
*expression to select all columns. -
Select all properties from the
userdata source. Give the object an alias ofdata. -
Select a pair of properties.
-
Select a specific property from the
userdata source. -
Select the property
cityfrom theaddressdata source.
FROM Clause
Syntax
Example 5. FROM Syntax
from = FROM _ dataSource
dataSource = collectionName ( ( _ AS )? _ collectionAlias )?
collectionName = IDENTIFIER
collectionAlias = IDENTIFIER
Here dataSource is the collection name against which the query is to run. Use AS to give the collection an alias you can use within the query. To use the default collection, without specifying a name, use _ as the data source.
Example
Example 6. FROM Examples
SELECT name FROM testScope.user;
SELECT user.name FROM testScope.users AS user;
SELECT user.name FROM testScope.users user;
-- These queries use the default scope and default collection (_default._default) in Couchbase.
SELECT name FROM _default._default;
SELECT user.name FROM _default._default AS user;
SELECT user.name FROM _default._default user;
JOIN Clause
Purpose
The JOIN clause enables you to select data from multiple data sources linked by criteria specified in the ON constraint. Currently only self-joins are supported. For example to combine airline details with route details, linked by the airline id - see Example 7.
Arguments
-
The
JOINclause starts with aJOINoperator followed by the data source. -
Five
JOINoperators are supported:-
JOIN,LEFT JOIN,LEFT OUTER JOIN,INNER JOIN, andCROSS JOIN. -
NOTE:
JOINandINNER JOINare the same, andLEFT JOINandLEFT OUTER JOINare the same.
-
-
The
JOINconstraint starts with theONkeyword followed by the expression that defines the joining constraints.
Example
Example 8. JOIN Examples
SELECT users.prop1, other.prop2
FROM testScope.users
JOIN users AS other ON users.key = other.key;
SELECT users.prop1, other.prop2
FROM testScope.users
LEFT JOIN users AS other ON users.key = other.key;
Example 9. Using JOIN to Combine Document Details
This example joins the documents from the routes collections with documents from the airlines collection using the document ID (id) of the airline document and the airlineId property of the route document.
SELECT *
FROM inventory.routes r
JOIN airlines a ON r.airlineId = META(a).id
WHERE a.country = "France";
WHERE Clause
Purpose
Specifies the selection criteria used to filter results. As with SQL, use the WHERE clause to choose which results are returned by your query.
GROUP BY Clause
Arguments
-
The
GROUP BYclause starts with theGROUP BYkeyword followed by one or more expressions. -
The
GROUP BYclause is normally used together with aggregate functions (e.g.COUNT,MAX,MIN,SUM,AVG). -
The
HAVINGclause allows you to filter the results based on aggregate functions - for example,HAVING COUNT(airlineId) > 100.
Example
Example 13. GROUP BY Examples
SELECT COUNT(airlineId), destination
FROM inventory.routes
GROUP BY destination;
SELECT COUNT(airlineId), destination
FROM inventory.routes
GROUP BY destination
HAVING COUNT(airlineId) > 100;
SELECT COUNT(airlineId), destination
FROM inventory.routes
WHERE destinationState = "CA"
GROUP BY destination
HAVING COUNT(airlineId) > 100;
ORDER BY Clause
Arguments
-
The
ORDER BYclause starts with theORDER BYkeyword followed by one or more ordering expressions. -
An ordering expression specifies an expressions to use for ordering the results.
-
For each ordering expression, the sorting direction can be specified using the optional
ASC(ascending) orDESC(descending) directives. Default isASC.
LIMIT Clause
OFFSET Clause
Expressions
An expression is a specification for a value that is resolved when executing a query. This section, together with Operators and Functions, which are covered in their own sections, covers all the available types of expressions.
Literals
Example 21. Boolean Examples
SELECT value
FROM testScope.testCollection
WHERE value = true;
SELECT value
FROM testScope.testCollection
WHERE value = false;
Numeric
Example 22. Numeric Syntax
numeric = -? ( ( . digit+ ) | ( digit+ ( . digit* )? ) ) ( ( E | e ) ( - | + )? digit+ )? digit = /[0-9]/
Example 23. Numeric Examples
SELECT
10,
0,
-10,
10.25,
10.25e2,
10.25E2,
10.25E+2,
10.25E-2
FROM testScope.testCollection;
Example 24. String Syntax
string = ( " character* " | ' character* ' ) character = ( escapeSequence | any codepoint except ", ' or control characters ) escapeSequence = \ ( " | ' | \ | / | b | f | n | r | t | u hex hex hex hex ) hex = hexDigit hexDigit hexDigit = /[0-9a-fA-F]/
|
The string literal can be double-quoted as well as single-quoted. |
Example 25. String Examples
SELECT firstName, lastName
FROM crm.customer
WHERE contact.middleName = "middle" AND contact.lastName = 'last';
Example 27. NULL Examples
SELECT firstName, lastName
FROM crm.customer
WHERE contact.middleName IS NULL;
Example 29. MISSING Examples
SELECT firstName, lastName
FROM crm.customer
WHERE contact.middleName IS MISSING;
Example 31. ARRAY examples
SELECT ["a", "b", "c"]
FROM testScope.testCollection
SELECT [property1, property2, property3]
FROM testScope.testCollection
Identifier
Purpose
An identifier references an entity by its symbolic name. Use an identifier for example to identify:
-
Column alias names
-
Database names
-
Database alias names
-
Property names
-
Parameter names
-
Function names
-
FTS index names
Example 34. Identifier Syntax
identifier = ( plainIdentifier | quotedIdentifier ) plainIdentifier = /[a-zA-Z_][a-zA-Z0-9_$]*/ quotedIdentifier = /`[^`]+`/
|
To use other than basic characters in the identifier, surround the identifier with the backticks ` character. For example, to use a hyphen (-) in an identifier, use backticks to surround the identifier. Please note that backticks are commonly used for string literals/interpolation in TypeScript/JavaScript. Therefore, you should be aware that backticks need to be escaped properly to function correctly in TypeScript/JavaScript. For more information, refer to Template Literal Types in TypeScript. |
Example 35. Identifier Examples
-- This query uses the default scope and default collection (_default._default) in Couchbase.
SELECT *
FROM _default._default;
SELECT *
FROM test-scope.test-collection;
SELECT key
FROM testScope.testCollection;
SELECT key$1
FROM test_Scope.test_Collection;
SELECT `key-1`
FROM testScope.testCollection;
Property Expression
Example 36. Property Expression Syntax
property = ( * | dataSourceName . _? * | propertyPath ) propertyPath = propertyName ( ( . _? propertyName ) | ( [ _? numeric _? ] _? ) )* propertyName = IDENTIFIER
-
Prefix the property expression with the data source name or alias to indicate its origin.
-
Use dot syntax to refer to nested properties in the propertyPath.
-
Use bracket (
[index]) syntax to refer to an item in an array. -
Use the asterisk (
*) character to represents all properties. This can only be used in the result list of theSELECTclause.
Example 37. Property Expressions Examples
SELECT *
FROM crm.customer
WHERE contact.firstName = 'daniel';
SELECT crm.customer.*
FROM crm.customer
WHERE contact.firstName = 'daniel';
SELECT crm.customer.contact.address.city
FROM crm.customer
WHERE contact.firstName = 'daniel';
SELECT contact.address.city, contact.phones[0]
FROM crm.customer
WHERE contact.firstName = 'daniel';
Any and Every Expression
Example 38. Any and Every Expression Syntax
arrayExpression = anyEvery _ variableName _ IN _ expression _ SATISFIES _ expression _ END
anyEvery = ( anyOrSome AND EVERY | anyOrSome | EVERY )
anyOrSome = ( ANY | SOME )
variableName = IDENTIFIER
-
The array expression starts with
anyEvery, where each possible combination has a different function as described below, and is terminated byEND.-
ANYorSOME: ReturnsTRUEif at least one item in the array satisfies the expression, otherwise returnsFALSE.+
ANYandSOMEare interchangeable.+
-
EVERY: ReturnsTRUEif all items in the array satisfies the expression, otherwise returnsFALSE. If the array is empty, returnsTRUE. -
( ANY | SOME ) AND EVERY: Same asEVERYbut returnsFALSEif the array is empty.
-
-
The
variableNamerepresents each item in the array. -
The
INkeyword is used to specify the array to be evaluated. -
The
SATISFIESkeyword is used to specify the expression to evaluate for each item in the array. -
ENDterminates the array expression.
Parameter Expression
Purpose
A parameter expression references a value from the api|Parameters assigned to
the query before execution.
|
If a parameter is specified in the query string, but no value has been provided, an error will be thrown when executing the query. |
Operators
Binary Operators
Table 2. Maths Operators
| Op | Description | Example |
|---|---|---|
|
Add |
|
|
Subtract |
|
|
Multiply |
|
|
Divide - see 1 |
|
|
Modulus |
|
-
If both operands are integers, integer division is used, but if one is a floating number, then float division is used. This differs from SQL++ for Server, which performs float division regardless. Use
DIV(x, y)to force float division in SQL++ for Mobile.
Table 3. Comparison Operators
| Op | Description | Example |
| ------------ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| = or == | Equals | WHERE v1 = v2<br/> WHERE v1 == v2 |
| != or <> | Not Equal to | WHERE v1 != v2<br/> WHERE v1 <> v2 |
| > | Greater than | WHERE v1 > v2 |
| >= | Greater than or equal to | WHERE v1 >= v2 |
| < | Less than | WHERE v1 < v2 |
| <= | Less than or equal to | WHERE v1 <= v2 |
| IN | Returns TRUE if the value is in the list or array of values specified by the right hand side expression; Otherwise returns FALSE. | WHERE 'James' IN contactsList |
| LIKE | String wildcard pattern matching, comparison - see 2. Two wildchards are supported:
• % Matches zero or more characters.
• Matches a single character. | WHERE name LIKE 'a%' <br/> WHERE name LIKE '%a' <br/> WHERE name LIKE '%or%' <br/> WHERE name LIKE 'a%o%' <br/> WHERE name LIKE '%_r%' <br/> WHERE name LIKE '%a%' <br/> WHERE name LIKE '%a__%' <br/> WHERE name LIKE 'aldo' <br/> |
| MATCH | String matching using FTS | WHERE v1-index MATCH "value" |
| BETWEEN | Logically equivalent to v1 >= start AND v1 <= end | WHERE v1 BETWEEN 10 AND 100 |
| IS NULL - see 3 | Equal to null | WHERE v1 IS NULL |
| IS NOT NULL | Not equal to null | WHERE v1 IS NOT NULL |
| IS MISSING | Equal to MISSING | WHERE v1 IS MISSING |
| IS NOT MISSING | Not equal to MISSING | WHERE v1 IS NOT MISSING |
| IS VALUED | Logically equivalent to IS NOT NULL AND MISSING | WHERE v1 IS VALUED |
| IS NOT VALUED | Logically equivalent to IS NULL OR MISSING | WHERE v1 IS NOT VALUED` |
-
Matching is case-insensitive for ASCII characters, case-sensitive for non-ASCII.
-
Use of
ISandIS NOTis limited to comparingNULLandMISSINGvalues (this encompassesVALUED). This is different fromapi|QueryBuilder, in which they operate as equivalents of==and!=.
Table 4. Comparing NULL and MISSING values using IS
| Op | Non-NULL Value |
NULL |
MISSING |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Logical Operators
Purpose
Logical operators combine expressions using the following boolean logic rules:
-
TRUEisTRUE, andFALSEisFALSE. -
Numbers
0or0.0areFALSE. -
Arrays and dictionaries are
FALSE. -
Strings and Blobs are
TRUEif the values are casted as a non-zero orFALSEif the values are casted as0or0.0. -
NULLisFALSE. -
MISSINGisMISSING.
|
This is different from SQL++ for Server, where:
|
|
Use the |
Table 5. Logical Operators
| Op | Description | Example |
|---|---|---|
|
Returns |
|
|
Returns |
|
Table 6. Logical Operators Table
a |
b |
a AND b |
a OR b |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This differs from SQL++ for Server in the following instances:
-
-
Server will return:
NULLinstead ofFALSE.
-
-
-
Server will return:
MISSINGinstead ofFALSE.
-
-
-
Server will return:
NULLinstead ofMISSING.
-
Unary Operators
Purpose
Three unary operators are provided. They operate by modifying an expression,
making it numerically positive or negative, or by logically negating its value
(TRUE becomes FALSE).
Table 8. Unary Operators
| Op | Description | Example |
|---|---|---|
|
Positive value |
|
|
Negative value |
|
|
Logical Negate operator, see 8 |
|
-
The
NOToperator is often used in conjunction with operators such asIN,LIKE,MATCH, andBETWEENoperators.-
NOToperation onNULLvalue returnsNULL. -
NOToperation onMISSINGvalue returnsMISSING.
-
COLLATE Operator
Usage
The collate operator is used in conjunction with string comparison expressions
and ORDER BY clauses. It allows for one or more collations. If multiple
collations are used, the collations need to be specified in a parenthesis. When
only one collation is used, the parenthesis is optional.
|
Collation is not supported by SQL++ for Server. |
Example 45. COLLATE Operator Syntax
collate = COLLATE _ ( collation | '(' collation ( _ collation )+ ')' )
collation = NO? (UNICODE | CASE | DIACRITICS)
Arguments
-
The available collation options are:
-
UNICODE: Conduct a Unicode comparison; the default is to do ASCII comparison. -
CASE: Conduct case-sensitive comparison -
DIACRITIC: Take accents and diacritics into account in the comparison; On by default. -
NO: This can be used as a prefix to the other collations, to disable them. For example, useNOCASEto enable case-insensitive comparison.
-
Example 46. COLLATE Operator Example
SELECT contact
FROM crm.customer
WHERE contact.firstName = "fred" COLLATE UNICODE;
SELECT contact
FROM crm.customer
WHERE contact.firstName = "fred" COLLATE (UNICODE CASE);
SELECT firstName, lastName
FROM crm.customer
ORDER BY firstName COLLATE (UNICODE DIACRITIC), lastName COLLATE (UNICODE DIACRITIC);
Conditional Operator
Purpose
The conditional (or CASE) operator evaluates conditional logic in a similar
way to the IF/ELSE operator.
Example 47. Conditional Operators Syntax
case = CASE _ ( expression _ )?
( WHEN _ expression _ THEN _ expression _ )+
( ELSE _ expression _)?
END
Both Simple Case and Searched Case expressions are supported. The syntactic
difference being that the Simple Case expression has an expression after the
CASE keyword.
-
Simple Case Expression
-
If the
CASEexpression is equal to the firstWHENexpression, the result is theTHENexpression. -
Otherwise, any subsequent
WHENclauses are evaluated in the same way. -
If no match is found, the result of the
CASEexpression is theELSEexpression, orNULLif noELSEexpression was provided.
-
-
Searched Case Expression
-
If the first
WHENexpression isTRUE, the result of this expression is itsTHENexpression. -
Otherwise, subsequent
WHENclauses are evaluated in the same way. -
If no
WHENclause evaluate toTRUE, then the result of the expression is theELSEexpression, orNULLif noELSEexpression was provided.
-
Functions
Aggregation Functions
Table 10. Aggregation Functions
| Function | Description |
|---|---|
|
Returns the average of all numeric values in the group. |
|
Returns the count of all values in the group. |
|
Returns the minimum numeric value in the group. |
|
Returns the maximum numeric value in the group. |
|
Returns the sum of all numeric values in the group. |
Array Functions
Table 11. Array Functions
| Function | Description |
|---|---|
|
Returns an array of the non- |
|
Returns the average of all non- |
|
Returns |
|
Returns the number of non- |
|
Returns the first non- |
|
Returns the largest non- |
|
Returns the smallest non- |
|
Returns the length of the array. |
|
Returns the sum of all non- |
Conditional Functions
Table 12. Conditional Functions
| Function | Description |
|---|---|
|
Returns the first non- |
|
Returns the first non- |
|
Returns the first non- |
|
Returns |
|
Returns |
Date and Time Functions
Table 13. Date and Time Functions
| Function | Description |
|---|---|
|
Returns the number of milliseconds since the unix epoch of the given ISO 8601 date input string. |
|
Returns the ISO 8601 UTC date time string of the given ISO 8601 date input string. |
|
Returns a ISO 8601 date time string in device local timezone of the given number of milliseconds since the unix epoch expression. |
|
Returns the UTC ISO 8601 date time string of the given number of milliseconds since the unix epoch expression. |
Full Text Search Functions
Table 14. FTS Functions
| Function | Description | Example |
|---|---|---|
|
||
|
Returns a numeric value indicating how well the current query result matches the full-text query when performing the MATCH. indexName is an IDENTIFIER for the FTS index. |
|
Maths Functions
Table 15. Maths Functions
| Function | Description |
|---|---|
|
Returns the absolute value of a number. |
|
Returns the arc cosine in radians. |
|
Returns the arcsine in radians. |
|
Returns the arctangent in radians. |
|
Returns the arctangent of |
|
Returns the smallest integer not less than the number. |
|
Returns the cosine of an angle in radians. |
|
Returns float division of |
|
Converts radians to degrees. |
|
Returns the e constant, which is the base of natural logarithms. |
|
Returns the natural exponential of a number. |
|
Returns largest integer not greater than the number. |
|
Returns integer division of |
|
Returns log base e. |
|
Returns log base 10. |
|
Returns the pi constant. |
|
Returns |
|
Converts degrees to radians. |
|
Returns the rounded value to the given number of integer digits to the right of the decimal point (left if digits is negative). Digits are 0 if not given. |
|
Returns rounded value to the given number of integer digits to the right of the decimal point (left if digits is negative). Digits are 0 if not given. |
|
Returns -1 for negative, 0 for zero, and 1 for positive numbers. |
|
Returns sine of an angle in radians. |
|
Returns the square root. |
|
Returns tangent of an angle in radians. |
|
Returns a truncated number to the given number of integer |
|
The behavior of the |
Pattern Searching Functions
Table 16. Pattern Searching Functions
| Function | Description |
|---|---|
|
Returns |
|
Return |
|
Returns the first position of the occurrence of the regular expression pattern within the input string expression. Returns |
|
Returns a new string with occurrences of |
String Functions
Table 17. String Functions
| Function | Description |
|---|---|
|
Returns |
|
Returns the length of a string. The length is defined as the number of characters within the string. |
|
Returns the lower-case string of the input string. |
|
Returns the string with all leading whitespace characters removed. |
|
Returns the string with all trailing whitespace characters removed. |
|
Returns the string with all leading and trailing whitespace characters removed. |
|
Returns the upper-case string of the input string. |
Type Checking Functions
Table 18. Type Checking Functions
| Function | Description |
|---|---|
|
Returns |
|
Returns |
|
Returns |
|
Returns |
|
Returns |
|
Returns |
|
Returns one of the following strings, based on the value of |
Type Conversion Functionsunctions
Table 19. Type Conversion Functions
| Function | Description |
|---|---|
|
Returns |
|
Returns |
|
Returns |
|
Returns |
|
Returns |
|
Returns |
QueryBuilder Differences
SQL++ for Mobile queries support all QueryBuilder features. See <<,Table 20>>
for the features supported by SQL++ for Mobile but not by QueryBuilder.
Table 20. QueryBuilder Differences
| Category | Components |
|---|---|
Conditional Operator |
|
Array Functions |
|
Conditional Functions |
|
Pattern Matching Functions |
|
Type Checking Functions |
|
Type Conversion Functions |
|
Query Parameters
You can provide runtime parameters to your SQL++ query to make it more flexible.
To specify substitutable parameters within your query string prefix the name
with $ - see: Example 51.
Example 51. Running a SQL++ Query
You can provide runtime parameters to your SQL++ query to make it more flexible. To specify substitutable parameters within your query string prefix the name with $ - see: Example 51.
const query = await database.createQuery(
'SELECT META().id AS docId FROM hotel WHERE country = $country'
);
const params = new Parameters();
params.setString('country','France')
query.parameters = params;
const resultSet = await query.execute();
-
Define a parameter placeholder
$country. -
Set the value of the
countryparameter.