Field Selection

A Query can specify which fields to fetch. The available fields are either

The requested fields are specified as a collection of Field structures in the field property on the Query.

Field Arguments

Arguments can be supplied to fields via the arguments key. These match the format described in the arguments documentation.

The schema response will specify which fields take arguments via its respective arguments key.

If a field has any arguments defined, then the arguments field must be provided wherever that field is referenced. All fields are required, including nullable fields.

Nested Fields

Queries can specify nested field selections for columns which have structured types (that is, not simply a scalar type or a nullable scalar type).

In order to specify nested field selections, the fields property of the Field structure, which is a NestedField structure.

If fields is omitted, the entire structure of the column's data should be returned.

If fields is provided, its value should be compatible with the type of the column:

Nested objects

For an object-typed column (whether nullable or not), the fields property should contain a NestedField with type object.

The fields property of the NestedField specifies a Field structure for each requested nested field from the objects.

Nested arrays

For an array-typed column (whether nullable or not), the fields property may contain a NestedField with type array.

The fields property of the NestedField should contain another NestedField structure, compatible with the type of the elements of the array. The selection function denoted by this nested NestedField structure should be applied to each element of each array.

Nested collections

For a column whose type is an array of objects (whether nullable or not), the fields property may contain a NestedField with type collection.

A connector should handle such fields by treating the nested array of objects as a collection. Such a field will include a nested Query, and the connector should execute that query in the context of this nested collection.

A response for a field with a fields property of type collection should be a RowSet which is computed from the nested collection by executing the specified query.

Note: support for nested collection queries is indicated by the query.nested_fields.nested_collections capability.

Nested fields and relationships

Within the scope of a nested object, that object should be used as the "current row" wherever that concept is appropriate:

  • In a Field::Column field, the column name points to a field of the nested object,
  • In a Field::Relationship field:

Note that only connectors that enable the relationships.nested capability will receive queries where relationships start from a nested object. Additionally, only connectors that enable the relationships.nested.array will receive queries where relationships start from nested objects inside nested arrays.

Examples

Simple column selection

Here is an example of a query which selects some columns from the articles collection of the reference data connector:

{
  "collection": "articles",
  "arguments": {},
  "query": {
    "fields": {
      "id": {
        "type": "column",
        "column": "id"
      },
      "title": {
        "type": "column",
        "column": "title"
      }
    }
  },
  "collection_relationships": {}
}

Example with Nested Object Types

Here is an example of a query which selects some columns from a nested object inside the rows of the institutions collection of the reference data connector:

{
  "collection": "institutions",
  "arguments": {},
  "query": {
    "fields": {
      "id": {
        "type": "column",
        "column": "id"
      },
      "location": {
        "type": "column",
        "column": "location",
        "fields": {
          "type": "object",
          "fields": {
            "city": {
              "type": "column",
              "column": "city"
            },
            "campuses": {
              "type": "column",
              "column": "campuses",
              "arguments": {
                "limit": {
                  "type": "literal",
                  "value": null
                }
              }
            }
          }
        }
      },
      "location_all": {
        "type": "column",
        "column": "location"
      }
    }
  },
  "collection_relationships": {}
}

Notice that the location column is fetched twice: once to illustrate the use of the fields property, to fetch a subset of data, and again in the location_all field, which omits the fields property and fetches the entire structure.

Example with Nested Array Types

Here is an example of a query which selects some columns from a nested array inside the rows of the institutions collection of the reference data connector:

{
  "collection": "institutions",
  "arguments": {},
  "query": {
    "fields": {
      "id": {
        "type": "column",
        "column": "id"
      },
      "staff": {
        "type": "column",
        "column": "staff",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": null
          }
        },
        "fields": {
          "type": "array",
          "fields": {
            "type": "object",
            "fields": {
              "last_name": {
                "type": "column",
                "column": "last_name"
              },
              "fields_of_study": {
                "type": "column",
                "column": "specialities",
                "arguments": {
                  "limit": {
                    "type": "literal",
                    "value": null
                  }
                }
              }
            }
          }
        }
      },
      "departments": {
        "type": "column",
        "column": "departments",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": null
          }
        }
      }
    }
  },
  "collection_relationships": {}
}

Notice that the staff column is fetched using a fields property of type array. For each staff member in each institution row, we apply the selection function denoted by its fields property (of type object). Specifically, the last_name and specialities properties are selected for each staff member.

Example with a Nested Collection

Here is an example of a query which computes aggregates over a nested collection inside the staff field of each row of the institutions collection:

{
  "collection": "institutions",
  "arguments": {},
  "query": {
    "fields": {
      "id": {
        "type": "column",
        "column": "id"
      },
      "staff_aggregates": {
        "type": "column",
        "column": "staff",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": null
          }
        },
        "field_path": [],
        "fields": {
          "type": "collection",
          "query": {
            "aggregates": {
              "count": {
                "type": "star_count"
              }
            }
          }
        }
      },
      "staff": {
        "type": "column",
        "column": "staff",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": null
          }
        },
        "fields": {
          "type": "array",
          "fields": {
            "type": "object",
            "fields": {
              "last_name": {
                "type": "column",
                "column": "last_name"
              },
              "first_name": {
                "type": "column",
                "column": "first_name"
              }
            }
          }
        }
      }
    }
  },
  "collection_relationships": {}
}

Note the staff_aggregates field in particular, which has fields with type collection.

Example with Nested Types and Relationships

This query selects institution data, and fetches author data if the first and last name fields match for any nested staff objects:

{
  "collection": "institutions",
  "arguments": {},
  "query": {
    "fields": {
      "name": {
        "type": "column",
        "column": "name"
      },
      "staff": {
        "type": "column",
        "column": "staff",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": null
          }
        },
        "fields": {
          "type": "array",
          "fields": {
            "type": "object",
            "fields": {
              "first_name": {
                "type": "column",
                "column": "first_name"
              },
              "last_name": {
                "type": "column",
                "column": "last_name"
              },
              "author": {
                "type": "relationship",
                "arguments": {},
                "query": {
                  "aggregates": null,
                  "fields": {
                    "id": {
                      "type": "column",
                      "column": "id"
                    },
                    "first_name": {
                      "type": "column",
                      "column": "first_name"
                    },
                    "last_name": {
                      "type": "column",
                      "column": "last_name"
                    }
                  }
                },
                "relationship": "author_by_first_and_last"
              }
            }
          }
        }
      }
    }
  },
  "collection_relationships": {
    "author_by_first_and_last": {
      "arguments": {},
      "column_mapping": {
        "first_name": ["first_name"],
        "last_name": ["last_name"]
      },
      "relationship_type": "object",
      "target_collection": "authors"
    }
  }
}

Note that the first_name and last_name properties in the column mapping are evaluated in the context of the nested staff object, and not in the context of the original institution row.

Example with Field Arguments

Here is an example of a query which selects some columns from a nested array inside the rows of the institutions collection of the reference data connector and uses the limit field argument to limit the number of items returned:

{
  "collection": "institutions",
  "arguments": {},
  "query": {
    "fields": {
      "id": {
        "type": "column",
        "column": "id"
      },
      "staff": {
        "type": "column",
        "column": "staff",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": 1
          }
        },
        "fields": {
          "type": "array",
          "fields": {
            "type": "object",
            "fields": {
              "last_name": {
                "type": "column",
                "column": "last_name"
              },
              "fields_of_study": {
                "type": "column",
                "column": "specialities",
                "arguments": {
                  "limit": {
                    "type": "literal",
                    "value": 2
                  }
                }
              }
            }
          }
        }
      },
      "departments": {
        "type": "column",
        "column": "departments",
        "arguments": {
          "limit": {
            "type": "literal",
            "value": null
          }
        }
      }
    }
  },
  "collection_relationships": {}
}

Requirements

  • If the QueryRequest contains a Query which specifies fields, then each RowSet in the response should contain the rows property, and each row should contain all of the requested fields.

See also