Skip to main content
The Search API provides two ways to store and retrieve text:
  • Text Store — preconfigured vector storage with hybrid search, deduplication, and grouping. No schema or index setup required.
  • Tables — low-level access to the vector database with full control over schema, indices, filters, and search operations.
Start with Text Store for most use cases. Use Tables when you need custom schemas, explicit index management, or advanced filter expressions. If you need an external-facing example that shows GraphRAG outperforming flat retrieval on a defined benchmark, see GraphRAG evaluation.

Create a text store

Provide a name and the embedding dimension for your vectors.
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: '<mka1-api-key>' });

const response = await mka1.search.textStore.createStore(
  {
    storeName: 'product_catalog',
    dimension: 3,
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Add texts to a text store

Add texts with their pre-computed embedding vectors. Duplicate texts are automatically skipped. The group field tags entries so you can delete or retrieve them as a set later.
const response = await mka1.search.textStore.addTexts(
  {
    storeName: 'product_catalog',
    addTextsRequest: {
      texts: [
        'Noise-cancelling over-ear headphones with 30-hour battery.',
        'Compact wireless earbuds with active noise cancellation.',
        'Studio monitor headphones with flat frequency response.',
      ],
      vectors: [
        [0.16, -0.08, 0.29],
        [0.14, -0.06, 0.31],
        [0.09, -0.12, 0.22],
      ],
      group: 'headphones',
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Search a text store

Pass a text query and its embedding vector. The service runs a hybrid search combining full-text and vector similarity.
const response = await mka1.search.textStore.search(
  {
    storeName: 'product_catalog',
    searchTextsRequest: {
      query: 'noise-cancelling headphones',
      vector: [0.16, -0.08, 0.29],
      limit: 5,
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Delete text from a text store

Remove specific entries by their exact text values.
const response = await mka1.search.textStore.deleteTexts(
  {
    storeName: 'product_catalog',
    deleteTextsRequest: {
      texts: [
        'Studio monitor headphones with flat frequency response.',
      ],
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Delete texts by group from a text store

Remove all entries that belong to one or more groups.
const response = await mka1.search.textStore.deleteTexts(
  {
    storeName: 'product_catalog',
    deleteTextsRequest: {
      groups: ['headphones'],
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Delete a text store

Remove the store and all of its data.
const response = await mka1.search.textStore.deleteStore(
  { storeName: 'product_catalog' },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Advanced Usage: Tables

Tables give you direct access to the underlying vector database. You define the schema, choose which fields to index, insert structured rows, and compose search operations yourself.

Schema fields

Each field in a table schema has a name, type, and optional properties.
TypeDescriptionIndex support
stringText dataFTS (full-text search)
int32-bit integerBTREE, BITMAP, LABEL_LIST
float64-bit floating pointBTREE, BITMAP, LABEL_LIST
datetimeTimestamp with optional timezoneBTREE
vectorFixed-dimension embeddingIVF_FLAT, IVF_PQ, IVF_HNSW_PQ, IVF_HNSW_SQ
listList of strings, ints, or floats
Set nullable to false for required fields. Add "index": "FTS" on a string field to enable full-text search at creation time. Vector fields require a dimensions property that matches your embedding size.

Create a search table

Define a table with a schema that describes your records. The example below creates a support knowledge base with a text field indexed for full-text search and a vector field for semantic search.
const response = await mka1.search.tables.create(
  {
    name: 'support_kb',
    schema: {
      fields: [
        { name: 'id', type: 'string', nullable: false },
        { name: 'content', type: 'string', nullable: false, index: 'FTS' },
        { name: 'category', type: 'string', nullable: false },
        { name: 'rating', type: 'float', nullable: true },
        { name: 'embedding', type: 'vector', nullable: false, dimensions: 3 },
      ],
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Insert rows

Insert records that match the table schema. You can send multiple rows in a single request.
const response = await mka1.search.tables.insertData(
  {
    tableName: 'support_kb',
    insertDataRequest: {
      data: [
        {
          id: 'doc_001',
          content: 'Reset your password from the account settings page.',
          category: 'account',
          rating: 4.7,
          embedding: [0.13, -0.09, 0.41],
        },
        {
          id: 'doc_002',
          content: 'Use two-factor authentication for added account security.',
          category: 'security',
          rating: 4.9,
          embedding: [0.07, -0.02, 0.36],
        },
      ],
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Search operations

Table search lets you compose multiple operations in a single request. Operations run in order — start with a primary search, then refine with filters, limits, or offsets. Primary operations initialize the result set:
OperationDescription
vector_searchFind rows closest to a query vector. Supports cosine, l2, dot, and hamming distance types.
ftsFull-text keyword search on one or more string fields.
Secondary operations refine the results:
OperationDescription
filterApply a SQL-like expression. Set prefilter to true to filter before ranking.
limitCap the number of returned rows.
offsetSkip the first N rows for pagination.
Use returnColumns to control which fields come back in the response.

Search the table

The example below combines a vector search with a pre-filter on the category field.
const response = await mka1.search.tables.search(
  {
    tableName: 'support_kb',
    searchRequest: {
      operations: [
        {
          type: 'vector_search',
          field: 'embedding',
          vector: [0.11, -0.06, 0.37],
          distanceType: 'cosine',
          limit: 5,
        },
        {
          type: 'filter',
          expression: "category = 'security'",
          prefilter: true,
        },
      ],
      returnColumns: ['id', 'content', 'category', 'rating'],
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Delete rows

Remove rows from a table using a filter expression.
const response = await mka1.search.tables.deleteData(
  {
    tableName: 'support_kb',
    deleteDataRequest: {
      filter: "id IN ('doc_001', 'doc_002')",
    },
  },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);

Delete a table

Remove the table and all of its data.
const response = await mka1.search.tables.delete(
  { tableName: 'support_kb' },
  { headers: { 'X-On-Behalf-Of': '<end-user-id>' } }
);