Officially out now: The TypeDB 3.0 Roadmap >>

Fetch stage

Fetch is primarily used to convert row answers into document (JSON) answers.

Syntax

A fetch stage can follow any other stage that produces rows (e.g., match, insert). It starts with the keyword fetch followed by curly braces {} with a fetch body inside of it. The fetch clause is terminal, meaning that it cannot be followed by any other pipeline stage.

Pipeline syntax
<pipeline stages>
fetch {
 <fetch body>
};

Where fetch body is either an all attributes statement:

Fetch with an all attributes statement based body
fetch {
 $<var>.*
};

Or a set of key-value statements:

Fetch with a key-value based body
fetch {
 "<key 0>": <some fetch statement 0>,
 ...
 "<key N>": <some fetch statement N>
};

These statements should be separated by commas. Comma at the end of the last statement is optional.

Key-value based body

<key N> is an arbitrary string literal.

<some fetch statement N> can be one of:

Fetch value
fetch {
  "key": $x
};
Fetch expression
fetch {
  "key": <expression>
};
Fetch an attribute of type
fetch {
  "key": $x.A
};
Fetch multiple attributes of type (when cardinality is not limited by 1)
fetch {
  "key": [ $x.A ]
};
Fetch a scalar single function result
fetch {
  "key": fun(...)
};
Fetch a scalar stream or single function result
fetch {
  "key": [ fun(...) ]
};
Fetch an inner fetch result
fetch {
  "key": [
    <read pipeline>
    fetch {
      <inner fetch body>
    }
  ]
};
Fetch an anonymous function scalar result
fetch {
  "key": (
    <read pipeline>
    return <return statement>
  )
};

The <return statement> can contain either a single or a stream function return statement. However, the parentheses () should be used only for scalar results.

See Functions for more information about function returns.

Fetch an anonymous function returning aggregates
fetch {
  "key": [
    <read pipeline>
    return <AGG 0>, ..., <AGG N>;
  ]
};
This is a short hand for…​
Composite statement example
fetch {
  "key": [
    <read pipeline>
    reduce $_0? = <AGG 1>, ... , $_n? = <AGG N>;
    return first $_0, ..., $_n;
  ]
};
Fetch a nested document
fetch {
  "key": {
    <fetch body>
  }
};

Understanding fetch

Fetch implements translation from classical rows to both more human-friendly and more REST API-friendly documents:

  • The structure of the output documents is identical to the structure of the fetch query.

  • The structure of the fetch query is flexible and fully controlled by users.

  • The output documents can be passed to any application that expects JSON inputs.

As it is a document, the order of keys is not guaranteed.

Fetch generates a document for each input row. When a variable from previous pipeline stages is referenced, the result is calculated individually based on the content of each row. However, if an unbounded subquery or function is used within fetch, the same result will be applied to all output documents, as it is executed identically for every row.

Usage

Refer to Syntax to explore different ways of fetch usage. The following example demonstrates a single fetch stage containing different values.

Every sub statement inside this fetch stage can be written as separate fetch es and can be considered as separate examples.

match
  $group isa group;
fetch {
  "name": $group.name,
  "tags": [$group.tag],
  "nested": {
    "double nested": {
      "tags": [$group.tag]
    }
  },
  "general mean karma": mean_karma(),
  "members": [
    match
      (group: $group, member: $member) isa group-membership;
    fetch {
      "member information": { $member.* },
    };
  ],
  "first username": (
    match
      (group: $group, member: $member) isa group-membership;
      $member has username $username;
    return first $username;
  ),
  "all usernames": [
    match
      (group: $group, member: $member) isa group-membership;
      $member has username $username;
    return { $username };
  ],
  "members mean karma": [
    match
      (group: $group, member: $member) isa group-membership;
      $member has karma $karma;
    return mean($karma);
  ]
};
Example TypeDB Console output

If two groups are inserted, the result of the query will contain two documents:

{
    "all usernames": [
        "Bob",
        "Alice"
    ],
    "first username": "Bob",
    "general mean karma": 3.2,
    "members": [
        {
            "member information": {
                "email": "bob@typedb.com",
                "karma": 2,
                "username": "Bob"
            }
        },
        {
            "member information": {
                "email": "alice@typedb.com",
                "karma": 4.4,
                "username": "Alice"
            }
        }
    ],
    "members mean karma": [ 3.2 ],
    "name": "UK hiking",
    "nested": {
        "double nested": {
            "tags": [
                "Hiking",
                "UK"
            ]
        }
    },
    "tags": [
        "Hiking",
        "UK"
    ]
}
{
    "all usernames": [ "Bob" ],
    "first username": "Bob",
    "general mean karma": 3.2,
    "members": [
        {
            "member information": {
                "email": "bob@typedb.com",
                "karma": 2,
                "username": "Bob"
            }
        }
    ],
    "members mean karma": [ 2 ],
    "name": "UK boxing",
    "nested": {
        "double nested": {
            "tags": [
                "Boxing",
                "UK"
            ]
        }
    },
    "tags": [
        "Boxing",
        "UK"
    ]
}

Notice that "general mean karma" is the same for two output documents as the function call is not bounded to match.