Skip to content

Node.js / Python / Go Client Libraries

MygramDB provides official TCP client libraries for application code. Use them when you want typed search, count, document lookup, FACET, runtime variables, and on-demand sync without building the TCP protocol yourself.

Scope

This page covers the application clients for Node.js, Python, and Go, plus where the bundled C/C++ SDK fits. The C/C++ API, CMake package, and pkg-config usage are documented on libmygramclient.

Support Matrix

LanguagePackageRequirementNotes
Node.jsmygramdb-clientNode.js 22+TypeScript types, pure JavaScript implementation, optional native binding
Pythonmygramdb-clientPython 3.9+asyncio, zero external dependencies, dataclass types
Gogithub.com/libraz/go-mygram-clientGo 1.23+standard library only, context.Context variants, safe for concurrent use
C / C++bundled libmygramclientC11 / C++17Installed SDK with C and C++ APIs, MygramDB::client_static / MygramDB::client_shared, and mygramclient.pc

Load data before querying

The clients are thin wrappers around MygramDB server commands. If existing rows have not been loaded yet, run SYNC <table> first. See SYNC Command.

Shared Concepts

What is raw boolean search?

Raw boolean search passes a full search expression — with AND, OR, NOT, and parentheses — straight to the server's query parser. Use it for conditions such as python OR (ruby AND rails) that the simple search() builder cannot express.

  • Use articles on a single-database server, or app_db.articles when the instance indexes tables from multiple databases.
  • search() / Search() is best for simple terms and AND/NOT-style searches.
  • For OR and parentheses, convert the expression and pass it to searchRaw() / SearchRaw() / search_raw().
  • BM25 scoring, highlighting, fuzzy search, and facets depend on the server-side table configuration.
  • Runtime variables and SYNC are TCP commands exposed by the client libraries.

Administrative commands require authentication

CONFIG, SET / SHOW VARIABLES, DUMP, REPLICATION, SYNC, OPTIMIZE, DEBUG, and CACHE require authentication. On an already connected client, send AUTH with MYGRAM_API_ADMIN_TOKEN before using them. Authentication belongs to the underlying TCP connection, so repeat it after every reconnect. Automatic reconnect cannot preserve authenticated state; authenticate before the next administrative operation after a reconnect. search, count, get, facet, and INFO remain unauthenticated.

Node.js / TypeScript

Install

bash
npm install mygramdb-client
bash
yarn add mygramdb-client
pnpm add mygramdb-client
bun add mygramdb-client
ts
import { createMygramClient } from 'mygramdb-client'

const client = createMygramClient({ host: 'localhost', port: 11016 })
await client.connect()

const results = await client.search('articles', 'hello', {
  limit: 100,
  sortColumn: 'created_at',
  sortDesc: true
})

console.log(`${results.totalCount} results`)

const count = await client.count('articles', 'technology')
const doc = await client.get('articles', '12345')

client.disconnect()
ts
import {
  convertSearchExpression,
  qualifyTableIdentity,
  parseTableIdentity
} from 'mygramdb-client'

const table = qualifyTableIdentity('articles', 'app_db') // app_db.articles
console.log(parseTableIdentity(table)) // { database: 'app_db', table: 'articles' }

const raw = convertSearchExpression('python OR (ruby AND rails)')
const res = await client.searchRaw(table, raw, { limit: 50 })

BM25 / HIGHLIGHT / FUZZY / FACET

ts
const ranked = await client.search('articles', 'machine learning', {
  sortColumn: '_score',
  sortDesc: true,
  limit: 10
})

const highlighted = await client.search('articles', 'golang', {
  highlight: {
    openTag: '<strong>',
    closeTag: '</strong>',
    snippetLen: 200,
    maxFragments: 3
  },
  sortColumn: '_score',
  sortDesc: true,
  limit: 10
})

const fuzzy = await client.search('articles', 'machne', {
  fuzzy: 1,
  limit: 10
})

const facets = await client.facet('articles', 'category', {
  query: 'machine learning',
  filters: { status: '1' },
  limit: 10
})

Runtime Variables and SYNC

ts
const adminToken = process.env.MYGRAM_API_ADMIN_TOKEN
if (!adminToken) {
  throw new Error('MYGRAM_API_ADMIN_TOKEN is required for administrative commands')
}

const authResponse = await client.sendCommand(`AUTH ${adminToken}`)
if (authResponse !== 'OK AUTHENTICATED') {
  throw new Error('MygramDB authentication failed')
}

await client.setVariable('logging.level', 'info')
console.log(await client.showVariables('logging%'))

await client.sync('app_db.articles')
console.log(await client.syncStatus())
await client.syncStop('app_db.articles')

Python

Install

bash
pip install mygramdb-client

Basic Search

python
import asyncio
from mygramdb_client import MygramClient, ClientConfig, SearchOptions

async def main():
    async with MygramClient(ClientConfig(host='localhost', port=11016)) as client:
        results = await client.search(
            'articles',
            'hello',
            SearchOptions(limit=100, sort_column='created_at', sort_desc=True),
        )
        print(f'{results.total_count} results')

        count = await client.count('articles', 'technology')
        doc = await client.get('articles', '12345')

asyncio.run(main())

Table Identities and Raw Boolean Search

python
import asyncio
from mygramdb_client import (
    ClientConfig,
    MygramClient,
    SearchRawOptions,
    convert_search_expression,
    parse_table_identity,
    qualify_table_identity,
)

async def main():
    async with MygramClient(ClientConfig(host='localhost', port=11016)) as client:
        table = qualify_table_identity('articles', 'app_db')  # app_db.articles
        print(parse_table_identity(table))                    # ('app_db', 'articles')

        raw = convert_search_expression('python OR (ruby AND rails)')
        res = await client.search_raw(table, raw, SearchRawOptions(limit=50))

asyncio.run(main())

HIGHLIGHT / FACET / SYNC

python
import asyncio
import os
from mygramdb_client import ClientConfig, FacetOptions, MygramClient, SearchOptions

async def main():
    async with MygramClient(ClientConfig(host='localhost', port=11016)) as client:
        res = await client.search_with_highlights(
            'articles',
            'golang',
            SearchOptions(limit=10, sort_column='_score', sort_desc=True),
        )

        facets = await client.facet(
            'articles',
            'category',
            FacetOptions(query='machine learning', filters={'status': '1'}, limit=10),
        )

        admin_token = os.environ.get('MYGRAM_API_ADMIN_TOKEN')
        if not admin_token:
            raise RuntimeError('MYGRAM_API_ADMIN_TOKEN is required for administrative commands')

        auth_response = await client.send_command(f'AUTH {admin_token}')
        if auth_response != 'OK AUTHENTICATED':
            raise RuntimeError('MygramDB authentication failed')

        await client.set_variable('logging.level', 'info')
        print(await client.show_variables('logging%'))

        await client.sync('app_db.articles')
        print(await client.sync_status())
        await client.sync_stop('app_db.articles')

asyncio.run(main())

Go

Install

bash
go get github.com/libraz/go-mygram-client

Basic Search

go
package main

import (
	"fmt"
	"log"

	mygram "github.com/libraz/go-mygram-client"
)

func main() {
	client := mygram.NewClient("localhost:11016")
	defer client.Close()

	if err := client.Connect(); err != nil {
		log.Fatal(err)
	}

	resp, err := client.Search("articles", "hello", mygram.SearchOptions{
		Limit:      100,
		SortColumn: "created_at",
		SortDesc:   true,
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Found %d results\n", resp.TotalCount)
}

Table Identities and Raw Boolean Search

go
table, _ := mygram.QualifyTableIdentity("articles", "app_db")
db, name, _ := mygram.ParseTableIdentity(table)
fmt.Println(db, name) // app_db articles

raw, _ := mygram.ConvertSearchExpression("python OR (ruby AND rails)")
resp, _ := client.SearchRaw(table, raw, mygram.SearchRawOptions{Limit: 50})
fmt.Println(resp.TotalCount)

resp, _ = client.SearchRawWithHighlights(
	table,
	raw,
	mygram.SearchRawOptions{Limit: 10},
)
fmt.Println(resp.Results)

BM25 / HIGHLIGHT / FUZZY / FACET

go
ranked, _ := client.Search("articles", "machine learning", mygram.SearchOptions{
	SortColumn: "_score",
	SortDesc:   true,
	Limit:      10,
})
fmt.Println(ranked.TotalCount)

highlighted, _ := client.Search("articles", "golang", mygram.SearchOptions{
	Highlight: &mygram.HighlightOptions{
		OpenTag:      "<strong>",
		CloseTag:     "</strong>",
		SnippetLen:   200,
		MaxFragments: 3,
	},
	SortColumn: "_score",
	SortDesc:   true,
	Limit:      10,
})
if len(highlighted.Results) > 0 {
	fmt.Println(highlighted.Results[0].Snippet)
}

fuzzy, _ := client.Search("articles", "machne", mygram.SearchOptions{
	Fuzzy: 1,
	Limit: 10,
})
fmt.Println(fuzzy.TotalCount)

facets, _ := client.Facet("articles", "category", mygram.FacetOptions{
	Query:   "machine learning",
	Filters: map[string]string{"status": "1"},
	Limit:   10,
})
fmt.Println(facets.Results)

Runtime Variables and SYNC

go
package main

import (
	"fmt"
	"log"
	"os"

	mygram "github.com/libraz/go-mygram-client"
)

func main() {
	adminToken := os.Getenv("MYGRAM_API_ADMIN_TOKEN")
	if adminToken == "" {
		log.Fatal("MYGRAM_API_ADMIN_TOKEN is required for administrative commands")
	}

	client := mygram.NewClient("localhost:11016")
	defer client.Close()
	if err := client.Connect(); err != nil {
		log.Fatal(err)
	}

	authResponse, err := client.SendCommand("AUTH " + adminToken)
	if err != nil {
		log.Fatal("MygramDB authentication command failed")
	}
	if authResponse != "OK AUTHENTICATED" {
		log.Fatal("MygramDB authentication failed")
	}

	if err := client.SetVariable("logging.level", "info"); err != nil {
		log.Fatal(err)
	}
	vars, err := client.ShowVariables("logging%")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(vars)

	if _, err := client.Sync("app_db.articles"); err != nil {
		log.Fatal(err)
	}
	status, err := client.SyncStatus()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(status)
	if _, err := client.SyncStop("app_db.articles"); err != nil {
		log.Fatal(err)
	}
}

Go concurrency

The Go client is designed for concurrent use. Use the context.Context variants such as SearchContext, SearchRawContext, and SyncContext when you need request-scoped cancellation or deadlines.

Server-Side References

FeatureDocumentation
Query syntax, AND / OR / NOTQuery Syntax
BM25 _scoreQuery Guide - Relevance Sort
HIGHLIGHTQuery Guide - Highlighting
FUZZYQuery Guide - Fuzzy Search
FACETQuery Guide - FACET
SYNCSYNC Command
Runtime variablesOperations

Repositories