Semogram Docs
OntologyAsk questions

Author a query

Define a reusable question with explicit inputs, outputs and bindings

You need a Semogram account with access to the workspace and a project in it. Definition and binding changes, query publication, execution and assertion review require their respective permissions. External reads and writes also require the selected plugin installation's credentials and access.

What a query defines

An ontology query describes a root class, its optional identity input, output fields, filters, ordering, schemas and policy. It resolves ontology terms through active read bindings. It is not raw SQL, not a source endpoint preview and not an unrestricted natural-language answer.

PartMeaning
ontology_package_id/versionCompiled project model selected by this definition
target.kindThe base method used to enumerate the root entities
input_schemaJSON Schema for runtime inputs
rootClass, optional identity selector and expected cardinality
output_mappingField names mapped to properties/relationships
output_schemaJSON Schema describing each result row
materializedSupported term filters, sort and result cap
policyRead-access restrictions/masking

A complete orders query

The project needs the operations model file, a compiled package/version and active virtual bindings: Order → entity_id, orderId → order_id, status → status, total → total on a readable Postgres endpoint. The physical records should contain stable entity IDs and numeric totals. Bindings select the endpoint; query YAML contains no credentials.

Open Ontology → Queries → New query. Choose manual authoring and enter the complete YAML below, or ask the assistant to prepare it. Replace the package UUID and numeric version. Validate the draft, resolve named issues and save before publication.

Create Demo orders for the compiled operations model. Enumerate Order through its virtual class binding, return id, order_id, status and total through the full term IRIs, accept no inputs, and validate each output row. Show the complete YAML and binding validation before saving.
query_definition:
  name: Demo orders
  slug: demo-orders
  ontology_package_id: <COMPILED_PACKAGE_UUID>
  ontology_package_version: <COMPILED_PACKAGE_VERSION_NUMBER>
  target:
    kind: virtual
  input_schema:
    type: object
    additionalProperties: false
  root:
    term_ref: https://example.com/operations#Order
    cardinality: many
  output_schema:
    type: object
    properties:
      id: { type: string }
      order_id: { type: string }
      status: { type: string }
      total: { type: number }
    required: [id, order_id, status, total]
  output_mapping:
    id: { term_ref: https://example.com/operations#Order }
    order_id: { term_ref: https://example.com/operations#orderId }
    status: { term_ref: https://example.com/operations#status }
    total: { term_ref: https://example.com/operations#total }

Download this YAML. content in query-create requests is the complete YAML string, not a nested object substituted for the resource body. HTTP POST /ontology/queries and MCP query_create accept name/content/authoringMode; MCP also requires idempotencyKey. Interface reference separates these actions.

Inputs and identity

To select one known Order, add a declared string order_id input and set root.identity to term_ref https://example.com/operations#orderId, input order_id. Use a cardinality appropriate to that selector. Execute with {"order_id":"O-001"}; the input name is part of your own query contract, not an automatic field name.

JSON schemas use supported draft-07 behavior. Values are not coerced, defaults are not silently inserted and unknown properties are not stripped. Use explicit nullable types for missing optional outputs. Publication requires both input/output schemas to explicitly describe objects; the output schema validates individual rows, not the enclosing HTTP response.

Relationships

For a materialized Order→Customer link, an output mapping can use relationship.term_ref with the full placedBy IRI, optional target_term_ref Customer and cardinality, then nested fields for Customer properties. The model, stored subject/object IDs and active relationship/property bindings all need to agree. Declaring the relationship in Turtle does not create links.

Filters and deterministic ordering

Supported property conditions include equals, not_equals, one_of, exists and numeric/date/text range bounds gt/gte/lt/lte. A runtime input names a declared parameter. Write one range bound per filter; two filters on the same term form a range. Sorting uses term references and asc/desc. A cap limits returned records, not proof that every upstream record was scanned.

Inside a complete query_definition
materialized:
  filters:
    - { term_ref: "https://example.com/operations#total", gte: 100 }
    - { term_ref: "https://example.com/operations#total", lte: 200 }
  sort:
    - { term_ref: "https://example.com/operations#orderId", direction: asc }
  limit: 100

This fragment does not replace the full query definition. Validate filter behavior against the selected read method and fixture, particularly with virtual/mixed sources. The label materialized is the serialized filter section; it is not an instruction to persist records.

Validate versus execute

Validation checks parsing, schema, known terms, bindings and supported resolution. It does not establish live credentials, data freshness or returned values. Save a draft, publish the reviewed version, then execute a known fixture. Inspect result diagnostics before expanding the query.