Skip to content
This repository has been archived by the owner on Dec 22, 2023. It is now read-only.

Protocol Query

Rick Mak edited this page Apr 7, 2017 · 1 revision

Query

Expression

Expression states the value to be compared in a predicate. Expression can be one of the followings:

  • data type (See DataType)

    Specify defined data type by following DataType. The value of this expression is literal, meaning evaluation does not require traversing an object graph. This is usually the right hand side (RHS) of a predicate.

  • object key path

    Key path is specified by combining the keys to be traversed in the object graph to evaluate a value. Keys are combined with a period (.). This is usually the left hand side (LHS) of a predicate.

    When in transmit, key path is wrapped inside an object to distinguish it from ordinary strings.

    {"$type": "keypath", "$val": "city.name"}

Examples

  • To find a student by name in the database, you need to compare the name property of the student with a literal string. For example, you compare {"$type": "keypath", "$val": "name"} (an object key path) with "Peter" (a string).

  • If each student contains a reference to a city, and each city has a name property, you can find students living in some city by comparing a key path with a literal string. For example, {"$type": "keypath", "$val": "city.name"} (an object key path) with "Hong Kong" (a string).

  • To find students by date of birth, compare key path with a datetime object, such as {"$type": "keypath", "$val": "birthdate"} (key path) and {"$type": "date", "$date": "2015-02-02T01:43:19+00:00"} (datetime)

Predicate

Predicate is used to filter objects satisfying a desired condition. In the protocol, a predicate is structrual data defining the condition.

Comparison Predicate

A comparison predicate is formed by a comparison operator and a number of expressions. The operator specifies how the expressions are compared to evaluate if the condition is satisfied.

  • ==: expression1 is equal to expression2

    ["eq", /* expression1 */, /* expression2 */]

  • >: expression1 is greater than expression2

    ["gt", /* expression1 */, /* expression2 */]

  • <: expression1 is less than expression2

    ["lt", /* expression1 */, /* expression2 */]

  • >=: expression1 is greater than or equal to expression2

    ["gte", /* expression1 */, /* expression2 */]

  • <=: expression1 is less than or equal to expression2

    ["lte", /* expression1 */, /* expression2 */]

  • <>: expression1 is not equal to expression2

    ["neq", /* expression1 */, /* expression2 */]

Examples

  • Find an object's city property having a certain name.

    ["eq", {"$type": "keypath", "$val": "city.name"}, "Hong Kong"]
    
  • Find birth date less than certain date.

    ["lt", {"$type": "keypath", "$val": "birthdate"},
    {"$type": "date", "$date": "2015-02-02T01:43:19+00:00"}]
    

Compound Predicate

A compound predicate is formed by combining an operator and a number of other predicates.

  • AND: predicate is satisfied when all its sub-predicates are satisfied. Specify at least two sub-predicates.

    ["and", /* predicate1 */, /* predicate2 */, /* predicate3 */]

  • OR: predicate is satisfied when any of its sub-predicates are satisfied. Specify at least two sub-predicates.

    ["or", /* predicate1 */, /* predicate2 */, /* predicate3 */]

  • NOT: predicate is satisfied if its sub-predicate is not satisfied.

    ["not", /* predicate1 */]

Examples

  • An object with certain name and city name.

    ["and",
        ["eq", {"$type": "keypath", "$val": "name"}, "Peter"],
        ["eq", {"$type": "keypath", "$val": "city.name"}, "Hong Kong"]
    ]
    

Sort Descriptor

Sort descriptor defines how the records are to be sorted when they are queried from server. Sort descriptors are specified in an array of sort descriptor in the order of sort priority.

Individaul sort descriptor consists of:

  • key path (the key path in the object graph to be sorted)

  • sort order (how the values are to be ordered, either asc for ascending, or desc for descending)

Examples

  • Sort by name first in ascending order, then by birth date in descending order.

    [
        [{"$type": "keypath", "$val": "name"}, "asc"],
        [{"$type": "keypath", "$val": "location"}, "desc"]
    ]
    

Eager Loading

With eager loading, the server returns records referenced by queried records. This is done by specifying an array of key paths that the server will return for each individual record satisfying the predicate.

Eager loading works as if additional record:fetch is called for each referenced objects and the result is returned in the same request.

Examples

Suppose we are quering for students that satisfy certain predicates. With eager loading specified like this:

[
    {"$type": "keypath", "$val": "parent"}
    {"$type": "keypath", "$val": "city.mayor"}
]

The following records are returned in addition to matching students:

  • parent: records referenced by the parent property
  • city: records referenced by the city property
  • city.mayor: records referenced by the mayor property of records referenced by the city property.

Discussions

  • To sort records with geolocations by ascending distance from a certain point, we need support for functions, such as:

    [
        ["func", "distance",
         {"$type": "keypath", "$val": "location"},
         {"$type": "geo", "$lat": 40.689167, "$lng": -74.044444}
        ],
        "asc"
    ]