Search by

adachsoft / vector-store-json-file

Arkadiusz Adach

JSON file based implementation of vector store contracts

Package info

gitlab.com/a.adach/vector-store-json-file

Issues

pkg:composer/adachsoft/vector-store-json-file

Statistics

Installs: 21

Dependents: 1

Suggesters: 0

Stars: 0

v0.4.0 2026-10-30 08:53 UTC

This package is auto-updated.

Last update: 2026-10-30 07:58:06 UTC


README

Overview

adachsoft/vector-store-json-file is a file-based implementation of the VectorStoreInterface from the adachsoft/vector-store-contracts package.

Each vector collection is stored as a single JSON file on disk. The JSON file contains:

  • global configuration of the collection (dimensions, distance metric),
  • all vector records (embeddings),
  • arbitrary metadata attached to each record.

This package is intended for small to medium vector stores where a simple JSON file is sufficient and a database or external service would be overkill.

Requirements

  • PHP 8.3 or higher
  • Composer
  • Runtime dependencies:
    • adachsoft/vector-store-contracts (vector store contracts and DTOs)
    • adachsoft/collection (immutable collections for vectors and metadata)

Installation

Install the package via Composer:

composer require adachsoft/vector-store-json-file

Usage

Basic store setup

use AdachSoft\VectorStoreJsonFile\JsonFileVectorCollectionRepositoryFactory;
use AdachSoft\VectorStoreJsonFile\JsonFileVectorStore;
use AdachSoft\VectorStoreContracts\Enum\DistanceMetricEnum;

$storagePath = __DIR__ . '/var/vector-store';

// Create the store instance (the directory must exist and be writable)
$store = new JsonFileVectorStore(
    $storagePath,
    new JsonFileVectorCollectionRepositoryFactory(),
);

// Create a new collection backed by a single JSON file
$store->createCollection('documents', 384, DistanceMetricEnum::COSINE);

// Get a repository for this collection
$repository = $store->getCollection('documents');

Upserting and searching

use AdachSoft\VectorStoreContracts\Collection\FilterCollection;
use AdachSoft\VectorStoreContracts\Collection\FloatVectorCollection;
use AdachSoft\VectorStoreContracts\Collection\MetadataCollection;
use AdachSoft\VectorStoreContracts\Dto\FilterExpressionDto;
use AdachSoft\VectorStoreContracts\Dto\SearchQueryDto;
use AdachSoft\VectorStoreContracts\Dto\VectorRecordDto;
use AdachSoft\VectorStoreContracts\Enum\FilterOperatorEnum;

// Upsert a vector record
$record = new VectorRecordDto(
    'doc-123',
    // 384-dimensional vector (example values)
    new FloatVectorCollection([0.1, 0.2, 0.3, 0.4 /* ... */]),
    new MetadataCollection([
        'category' => 'technology',
        'technologies' => ['php', 'typescript'],
        'language' => 'en',
    ]),
);

$repository->upsert($record);

// Build a search query
$query = new SearchQueryDto(
    new FloatVectorCollection([0.11, 0.21, 0.31, 0.41 /* ... */]), // query vector
    5,                                                               // topK
    new FilterCollection(['language' => 'en']),
    null,                                                            // optional minimum score
);

// Execute the search
$results = $repository->search($query);

foreach ($results as $result) {
    $record = $result->record;
    $score  = $result->score;

    // Handle the result (e.g. display ID and score)
}

Batch operations

Use upsertBatch() to insert or replace multiple records and deleteBatch() to remove multiple UUIDs:

use AdachSoft\VectorStoreContracts\Collection\RecordUuidCollection;
use AdachSoft\VectorStoreContracts\Collection\VectorRecordDtoCollection;

$repository->upsertBatch(new VectorRecordDtoCollection([$record]));
$repository->deleteBatch(new RecordUuidCollection(['doc-123', 'doc-456']));

Batch upserts validate every vector dimension before writing; if validation fails, no record in the batch is persisted. Repeated UUIDs in a batch use the last record, and empty batches are no-ops.

Metadata filters

Scalar filter values use the EQUALS operator. Legacy array filter values use ANY. Use FilterExpressionDto when the operator must be explicit:

$query = new SearchQueryDto(
    new FloatVectorCollection([0.11, 0.21, 0.31, 0.41 /* ... */]),
    5,
    new FilterCollection([
        'technologies' => new FilterExpressionDto(
            FilterOperatorEnum::ALL,
            ['php', 'typescript'],
        ),
    ]),
    null,
);

Metadata values can be scalars or flat indexed or associative arrays containing only scalars. Nested arrays, objects, and null values are not supported.

Concurrent writes

Writes to the same collection are synchronized between cooperating PHP processes on the same host using an exclusive lock file named <collection>.json.lock. Updated documents are written to uniquely named temporary files and atomically renamed into place. Lock files are intentionally left in the storage directory.

Using the factory

If you prefer configuration-based creation, you can use the factory:

use AdachSoft\VectorStoreJsonFile\JsonFileVectorStoreFactory;

$factory = new JsonFileVectorStoreFactory();

$store = $factory->create([
    'storage_path' => __DIR__ . '/var/vector-store',
]);

Testing

This project includes a test suite based on the contract tests from adachsoft/vector-store-contracts.

Run tests with:

vendor/bin/phpunit

The test configuration is defined in phpunit.xml in the project root.

Code style and static analysis

The project uses adachsoft/php-code-style for a unified code style, Rector rules and PHPStan configuration.

Convenience Composer scripts:

composer cs:check  # run PHP-CS-Fixer in dry-run mode
composer cs:fix    # fix coding style issues
composer stan      # run PHPStan analysis
composer rector    # run Rector refactorings

License

This library is open-sourced under the MIT license. See the license field in composer.json for details.