• English
  • VQuery

    Turn raw data into analytical results with a consistent query DSL.

    VQuery is a query engine for analytics. It provides dataset management, declarative queries, and SQL compilation in browsers and Node.js. It can also serve as the query layer of a VBI connector.

    Quick start · Query examples · Try it online

    Features

    CapabilityDescription
    Dataset managementLoad JSON or CSV data, define field schemas, and manage datasets per instance.
    Declarative queriesCombine select, where, groupBy, having, orderBy, and limit to describe your analysis.
    AggregationCalculate sums, averages, distinct counts, and more; group dates by year, quarter, month, and other intervals.
    SQL compilationCompile the same query DSL into MySQL or DuckDB SQL with parameters.
    Storage optionsUse in-memory storage by default, or explicitly enable IndexedDB to persist data across sessions.

    Quick start

    This example creates a dataset, queries total sales by region, and releases resources. Run the code blocks in order in a single module that supports top-level await.

    Install

    npm
    yarn
    pnpm
    bun
    deno
    npm install @visactor/vquery

    Create a dataset

    Provide a stable ID, field types, and source data. This example uses a JSON array and requires no database service.

    query.ts
    import { VQuery, type VQueryDSL } from '@visactor/vquery'
    
    const vquery = new VQuery()
    
    await vquery.createDataset(
      'sales',
      [
        { name: 'region', type: 'string' },
        { name: 'sales', type: 'number' },
      ],
      {
        type: 'json',
        rawDataset: [
          { region: 'East', sales: 120 },
          { region: 'West', sales: 80 },
          { region: 'East', sales: 180 },
        ],
      },
    )

    Describe the query

    Select the region, sum its sales, and sort by total sales in descending order.

    const query: VQueryDSL<{ region: string; sales: number }> = {
      select: [
        'region',
        { field: 'sales', alias: 'totalSales', aggr: { func: 'sum' } },
      ],
      groupBy: ['region'],
      orderBy: [{ field: 'totalSales', order: 'desc' }],
    }

    Run the query

    Connect to the dataset and execute the query. The returned dataset can be used in a table or passed to a visualization.

    const dataset = await vquery.connectDataset('sales')
    
    try {
      const result = await dataset.query(query)
      console.table(result.dataset)
      // [{ region: 'East', totalSales: 300 },
      //  { region: 'West', totalSales: 80 }]
    } finally {
      await dataset.disconnect()
      await vquery.close()
    }

    Core concepts

    Datasets and schemas

    A dataset combines an ID, field definitions, and a data source. createDataset() registers data, connectDataset() provides a query entry point, and disconnect() releases its query resources. Use dropDataset() to remove a registered dataset.

    Query DSL

    VQueryDSL describes the data you need. where filters rows before aggregation, groupBy defines groups, and having filters aggregated results. Save query configurations as JSON to reuse them in subsequent analyses.

    SQL compilation

    For data stored in a database, use compileQuery() independently. The compiler returns SQL and parameters; your application manages the database connection and execution.

    import { compileQuery } from '@visactor/vquery'
    
    const { sql, parameters } = compileQuery(query, {
      table: 'sales',
      dialect: 'mysql', // Also supports 'duckdb'
      columns: [
        { name: 'region', type: 'string' },
        { name: 'sales', type: 'number' },
      ],
    })

    Storage and runtime

    Node.js and browser entrypoints use in-memory query and storage adapters by default. No IndexedDB API is required. Each instance owns its datasets; closing the instance or reloading the page discards data in the default storage.

    Explicitly enable enableIndexedDB to persist dataset schemas and sources across sessions:

    const persistentQuery = new VQuery({ enableIndexedDB: true })
    IndexedDB only changes storage

    The runtime must support IndexedDB. Queries still run through the in-memory query adapter. Omitting the option, passing empty options, or setting it to false uses in-memory storage.

    Working with VBI and VSeed

    VBI manages analysis configurations and requests data through connectors. VQuery executes filters and aggregations. VSeed turns query results and chart semantics into VChart / VTable specs. You can also use VQuery independently to supply data to existing tables, charts, or APIs.

    Next steps