RQL - Raven Query Language
-
Queries in RavenDB use a SQL-like language called RQL (Raven Query Language).
-
RQL exposes the RavenDB query pipeline in a straightforward and accessible manner
that is easy to use and interact with. -
Any query written using high-level Session methods (
Query
,DocumentQuery
)
is translated by the client to RQL before being sent to the server for execution. -
A query can be written with RQL directly by either:
- Using the Session's
RawQuery
method - Making a query from the Query view in Studio
- Using the Session's
-
Learn more about querying from the session in this Query Overview.
-
In this page:
The query pipeline
The query pipeline in RavenDB includes the following main stages:
-
Detect query source (
from
)-
Based on your query, RavenDB will determine the appropriate data source from which to retrieve results.
-
Note: all queries in RavenDB use an index to provide results, even when you don't specify one.
-
The following options are available:
-
from index
- Explicitly specify which index to use. -
from collection
- Specify the collection to query.
RavenDB will decide which index will be used depending on the query criteria.
-
-
Learn more about these query scenarios in this Query Overview.
-
-
Filter the data (
where
)- The index is scanned for records that match the query predicate.
-
Include related documents (
include
)- Related documents that are included in the query will be retrieved and returned to the client
along with the resulting matching documents, reducing the need to do another network round trip
to the database when accessing the included documents.
- Related documents that are included in the query will be retrieved and returned to the client
-
Sort results (
order by
)- Query results can be sorted.
For example, you can order by a field value, by the resulting documents' score, by random ordering, etc.
- Query results can be sorted.
-
Limit results (
limit
)- You can specify the number of results you want to get back from the query
and the number of results you want to skip.
- You can specify the number of results you want to get back from the query
-
Project results (
select
)-
Projections are specified when you need to retrieve only specific document fields, instead of the whole full document. This reduces the amount of data sent over the network and is useful when only partial data is needed. When projections are Not defined on the query - then the full document content is retrieved from the document storage.
-
Projections are applied as the last stage after the query has been processed, filtered, sorted, and paged.
This means that the projection doesn't apply to all the documents in the database,
only to the results that are actually returned. -
Data can be loaded (
load
) from related documents to be used in the projected fields. -
For each record, the server extracts the requested field:
If a field is stored in the index - the server will fetch it from the index.
If a field is Not stored in the index - the server will fetch it from the document storage.
-
-
Return results to the client.
RQL keywords and methods
The following keywords and methods are available in RQL:
- DECLARE
-
FROM
- index
- GROUP BY
- WHERE
- ORDER BY
- LOAD
-
SELECT
- DISTINCT
- key()
- sum()
- count()
- facet()
- timeseries()
- counter()
- LIMIT
- UPDATE
- INCLUDE
- WITH
- MATCH
With the following operators:
- >=
- <=
- <> or !=
- <
- >
- = or ==
- BETWEEN
- IN
- ALL IN
- OR
- AND
- NOT
- (
- )
And the following values:
- true
- false
- null
- string e.g. 'John' or "John"
- number (long and double) e.g. 17
- parameter e.g. $param1
declare
You can use the declare
keyword to create a JavaScript function that can then be called from a select
clause when using a projection.
JavaScript functions add flexibility to your queries as they can be used to manipulate and format retrieved results.
// Declare a JavaScript function
declare function output(employee) {
// Format the value that will be returned in the projected field 'FullName'
var formatName = function(x){ return x.FirstName + " " + x.LastName; };
return { FullName : formatName(employee) };
}
// Query with projection calling the 'output' JavaScript function
from Employees as employee select output(employee)
Values are returned from a declared Javascript function as a set of values rather than in a nested array to ease the projection of retrieved values. See an example for this usage here.
from
The keyword from
is used to determine the source data that will be used when the query is executed.
The following options are available:
- Query a specific collection:
from <collection-name>
// Full collection query
// Data source: The raw collection documents (Auto-index is Not created)
from "Employees"
// Collection query - by ID
// Data source: The raw collection documents (Auto-index is Not created)
from "Employees" where id() = "employees/1-A"
// Dynamic query - with filtering
// Data source: Auto-index (server uses an existing auto-index or creates a new one)
from "Employees" where FirstName = "Laura"
- Query all documents:
from @all_docs
// All collections query
// Data source: All raw collections (Auto-index is Not created)
from @all_docs
// Dynamic query - with filtering
// Data source: Auto-index (server uses an existing auto-index or creates a new one)
from @all_docs where FirstName = "Laura"
- Query an index:
from index <index-name>
// Index query
// Data source: The specified index
from index "Employees/ByFirstName"
// Index query - with filtering
// Data source: The specified index
from index "Employees/ByFirstName" where FirstName = "Laura"
where
Use the where
keyword with various operators to filter chosen documents from the final result-set.
Operator: >=
, <=
, <>
, !=
, <
, >
, =
, ==
These basic operators can be used with all value types, including 'numbers' and 'strings'.
For example, you can return every document from the Companies collection
whose field value = a given input.
from "Companies"
where Name = "The Big Cheese" // Can use either '=' or'=='
Filtering on nested properties is also supported.
So in order to return all companies from 'Albuquerque' we need to execute following query:
from "Companies"
where Address.City = "Albuquerque"
Operator: between
The operator between
returns results inclusively, and the type of border values used must match.
It works on both 'numbers' and 'strings' and can be substituted with the >=
and <=
operators.
from "Products"
where PricePerUnit between 10.5 and 13.0 // Using between
from "Products"
where PricePerUnit >= 10.5 and PricePerUnit <= 13.0 // Using >= and <=
Operator: in
The operator in
is validating if a given field contains passed values.
It will return results if a given field matches any of the passed values.
from Companies
where Name in ('The Big Cheese', 'Unknown company name')
from Orders
where Lines[].ProductName in ('Chang', 'Spegesild', 'Unknown product name')
Operator: all in
This operator checks if all passes values are matching a given field.
Due to its mechanics, it is only useful when used on array fields.
The following query will yield no results in contrast to the in
operator.
from "Orders"
where Lines[].ProductName all in ("Chang", "Spegesild", "Unknown product name")
Removing 'Unknown product name' will return only orders that contain products with both
'Chang' and 'Spegesild' names.
from "Orders"
where Lines[].ProductName all in ("Chang", "Spegesild")
Binary Operators: AND
, OR
, NOT
Binary operators can be used to build more complex statements.
The NOT
operator can only be used with one of the other binary operators creating OR NOT
or AND NOT
ones.
from "Companies"
where Name = "The Big Cheese" OR Name = "Richter Supermarkt"
from "Orders"
where Freight > 500 AND ShippedAt > '1998-01-01'
from "Orders"
where Freight > 500 AND ShippedAt > '1998-01-01' AND NOT Freight = 830.75
Subclauses: (
, )
Subclauses can be used along with binary operators to build even more complex logical statements.
group by
The keyword group by
is used to create an aggregation query.
Learn more in dynamic group by queries.
include
The keyword include
has been introduced to support:
- including related documents or counters in the query response
- including compare-exchange items in the query response
- highlighting results
- get query timings
- get explanations
order by
Use order by
to perform sorting.
Learn more in this sorting article.
select
Use select
to have the query return a projection instead of the full document.
Learn more in this projection article.
load
Use load
when you need to use data from a related document in projection.
See an example in this projection article.
limit
Use limit
to limit the number of results returned by the query.
Specify the number of items to skip from the beginning of the result set and the number of items to take (return).
This is useful when paging results.
// Available syntax options:
// =========================
from "Products" limit 5, 10 // skip 5, take 10
from "Products" limit 10 offset 5 // skip 5, take 10
from "Products" offset 5 // skip 5, take all the rest
update
To patch documents on the server-side, use update
with the desired JavaScript that will be applied to any document matching the query criteria.
For more information, please refer to this patching article.
with
The keyword with
is used to determine the data source of a graph query.
There are two types of with
clauses, regular with
and with edges
.
-
with:
with {from Orders} as o
The above statement means that the data source referred to by the aliaso
is the result of thefrom Orders
query. -
with edges:
with edges (Lines) { where Discount >= 0.25 select Product } as cheap
The above statement means that our data source is the propertyLines
of the source documents and we filter all lines that matchDiscount >= 0.25
query.
The destination referred to by thecheap
alias is the product pointed by theProduct
property of the order line.
match
The keyword match
is used to determine the pattern of a graph query.
match (Orders as o)-[Lines as cheap where Discount >= 0.25 select Product]->(Products as p)
The above statement means that we are searching for a pattern that starts with an order and traverse using the
order lines referred to by the Lines
property where their Discount
property is larger than 25% and the destination is the product referred to by the Product
property.
A match may contain an edge in both direction, a right edge would look like so (node1)-[right]->(node2)
and a left one would look like so (node1)<-[left]-(node2)
.
Any combination of edges is allowed in a match clause e.g.
(node1)-[right]->(node2)<-[left]-(node3)
The above match will actually be translated to:
(node1)-[right]->(node2)
and
(node3)-[left]->(node2)
where the and
is a set intersection between the two patterns.
RQL comments
Single-line comments:
- Single-line comments start with
//
and end at the end of that line.
// This is a single-line comment.
from "Companies"
where Name = "The Big Cheese" OR Name = "Richter Supermarkt"
from "Companies"
where Name = "The Big Cheese" // OR Name = "Richter Supermarkt"
Multiline comments:
- Multiline comments start with
/*
and end with*/
.
/*
This is a multiline comment.
Any text here will be ignored.
*/
from "Companies"
where Name = "The Big Cheese" OR Name = "Richter Supermarkt"
from "Companies"
where Name = "The Big Cheese" /* this part is a comment */ OR Name = "Richter Supermarkt"