Query output types


On this page

    Comunica supports different SPARQL query types, each of which may require different kinds of output. For example, SELECT queries returns a stream of bindings, CONSTRUCT and DESCRIBE returns a stream of quads, and ASK returns a boolean.

    This document gives an overview of how these different output types are represented.

    Query operation output type

    All relevant types and interfaces are exposed by the Query Operation bus.

    IActorQueryOperationOutput is a TypeScript union type over the following interfaces:

    Bindings output

    An output of type IActorQueryOperationOutputBindings looks as follows:

    interface IActorQueryOperationOutputBindings {
      type: 'bindings';
      context?: ActionContext;
      metadata?: () => Promise<{[id: string]: any}>;
      bindingsStream: BindingsStream;
      variables: string[];
      canContainUndefs: boolean;
    }

    The most important field in here is bindingsStream, which is of type BindingsStream. This is a stream containing Bindings, which are of type Map<string, RDF.Term> where keys are variable names prefixes with ?.

    Quads output

    An output of type IActorQueryOperationOutputQuads looks as follows:

    interface IActorQueryOperationOutputQuads {
      type: 'bindings';
      context?: ActionContext;
      metadata?: () => Promise<{[id: string]: any}>;
      quadStream: RDF.Stream & AsyncIterator<RDF.Quad>;
    }

    The most important field in here is quadStream, which is of type RDF.Stream containing RDF/JS quads.

    Boolean output

    An output of type IActorQueryOperationOutputBoolean looks as follows:

    interface IActorQueryOperationOutputQuads {
      type: 'bindings';
      context?: ActionContext;
      booleanResult: Promise<boolean>;
    }

    The most important field in here is booleanResult, which is a promise resolving to a boolean.

    Casting an unknown output type

    If your actor calls a query operation mediator, it will receive an output of type IActorQueryOperationOutput. If you want to operate on the results directly, and if you are not certain of the output type, you will have to check the type field of the output, and handle it accordingly.

    If you however know beforehand what the type will be, you can safely cast the output type with the following helper functions:

    • ActorQueryOperation.getSafeBindings: Returns IActorQueryOperationOutputBindings.
    • ActorQueryOperation.getSafeQuads: Returns IActorQueryOperationOutputQuads.
    • ActorQueryOperation.getSafeBoolean: Returns IActorQueryOperationOutputBoolean.

    For example, the minus query operation actor (@comunica/actor-query-operation-minus) can only operate on bindings streams. As such, it can safely cast outputs as follows:

    const leftResult: IActorQueryOperationOutputBindings = ActorQueryOperation.getSafeBindings(
      await this.mediatorQueryOperation.mediate({ operation: pattern.right, context }),
    );
    const rightResult: IActorQueryOperationOutputBindings = ActorQueryOperation.getSafeBindings(
      await this.mediatorQueryOperation.mediate({ operation: pattern.left, context }),
    );
    
    leftResult.bindingsStream.filter(...);