Skip to main content

Querying

Ditto provides a robust query engine that supports different filter operations. At a high-level, all queries work on a specific collection and are used to filter the collection. In addition, since Ditto works with data represented in JSON-compatible documents, the query syntax offers dot notation to reference keys within the document tree as shown below:

const collection = await ditto.store.collection('people').find("favoriteBook.title == 'The Great Gatsby'")

Using query variables with $args

Often, you will query with runtime variables. Instead of building or interpolating query strings, the query system will accept variables through an $args dictionary object.

const query = 'name == $args.name && age <= $args.age'const documents = await ditto.store.collection('people').find(query, {  age: 32,  name: 'Max',})

Find by _id

Every document contains it's own unique _id property. This property can be set or randomly assigned. When updating a single document within a collection you will most often find that document by it's _id property.

// finds the document with the specified _idfindByID("1234")// ORfind("_id == '1234'")

Sort

Before executing a query, you can specify to sort on a specific property. Call sort before a query is executed by specifying a specific property and a sort direction.

Note: Queries that do not specify a sort will assume to sort on the _id property.

The following example will sort on documents that have a mileage property

const sortedRedCars = await ditto.store.collection('cars').find("color == 'red'").sort('miles', 'ascending')

Limit

There are times where you need to limit the number of results that a query returns. Call limit before the query is executed to trim the number of results. This is best used with sort.

const sortedAndLimitedRedCars = await ditto.store.collection('cars').find("color == 'red'").sort('miles', 'ascending').limit(100)

Creating query strings

The Ditto query language is very similar to what you'd write in most if statements. In addition, we offer standard, easy-to-understand query condition operators that most developers should understand.

To refer to keys within the document's property tree, Ditto uses dot notation that should be familiar to most developers. Let's say we have a document like so:

{   "_id": "123abc",   "name": { "first": "Alan", "last": "Turing" },   "contact": { "phone": { "type": "cell", "number": "111-222-3333" } },   "work": { "street-line": "678 Johnson Street"}}

If you wanted to query for the last property nested in name, you will need to do the following:

"name.last == 'Turing'"

Keys in the query syntax by default must be alphanumeric or include underscore (a-zA-Z0-9). In addition, the key must start with an alpha characters first (a-zA-Z). If your key uses another character, such as a hyphen, you must use a brack syntax. To query for the "street-line" property underneath "work", you will need to do the following:

"work['street-line'] == '678 Johnson Street'"

Equality ==, Inequality

// finds documents which have a title equal to Harry Potter."title == 'Harry Potter'"
// finds documents which that are not of the title Lord of the Rings"title != 'Lord of the Rings'"

Comparisons - Greater Or Less Than >=, >, <, <=

// finds documents where the age is less than or equal to 18"age <= 18"// finds documents where the age is less than to 18"age < 18"// finds documents where the age is greater than or equal to 18"age >= 18"// finds documents where the age is greater than to 18"age > 18"

Compound - And &&, Or ||, Not !, Contains contains

Use && for a logical and Predicate; similar to SQLite's AND

// finds documents that have a theme property equal to "Dark" and a name property equally to "Light""theme == 'Dark' && name == 'Light'"

Use || for a logical or predicate; similar to SQL OR statements

// finds documents that are "Tom" or "Arthur""name == 'Tom' || name == 'Arthur'"

Use ! for a logical not predicate; similar to SQL NOT statements

// finds documents that are neither "Hamilton" nor "Morten""!(name == 'Hamilton' || name == 'Morten')"

Use contains(array, value) to check if an array contains a value.

// finds documents who have a `connectionType` property and checks if it equals any of the values in a defined array"contains(['bluetooth', 'wifidirect'], connectionType)"

String Operations

Use starts_with(property, test) to test if a property with a string value starts with a test string

// finds documents with a title property that begins with "Lord""starts_with(title, 'Lord')"

Use ends_with(property, test) to test if a property with a string value ends with a test string

// finds documents with a title property that ends with "Rings""ends_with(title, 'Rings')"

Use regex(property, test) to see if a property with a string value passes a Regular Expression. Click here for a reference.

// finds documents which has a title property that only comprises of upper and lowercase letters, numbers, and underscores. "regex(title, '^([A-Za-z]|[0-9]|_)+$')"
// A title property of "abc129_24A" will pass// A title property of "abc129_24A  3" will not pass

Queries also parse ISO-8601 date strings as comparable dates

"created_at >= '2022-04-29T00:55:31.859Z'"

Booleans

Use when your property is of type Boolean, use value == false or value == true explicitly.

//finds documents which have an 'isDeleted' boolean propety set to `true`"isDeleted == true"
//finds documents which have an 'isDeleted' boolean propety set to `false`"isDeleted == false"