Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Neo4J Store Laravel Package

symfony/ai-neo4j-store

Neo4j Store integration for Symfony AI Store, enabling use of Neo4j as a vector store with support for vector indexes. Includes links to Neo4j documentation and Symfony AI resources for contributing and reporting issues.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup Steps

  1. Install Dependencies

    composer require symfony/ai-neo4j-store neo4j/neo4j-php-client
    
  2. Configure Neo4j Connection Add to .env:

    NEO4J_URI=bolt://localhost:7687
    NEO4J_USERNAME=neo4j
    NEO4J_PASSWORD=your_password
    
  3. Set Up Neo4j Schema Run this Cypher query in Neo4j Browser:

    CREATE SEMANTIC INDEX `embedding_index`
    FOR (n:Document)
    OPTIONS {
      `indexConfig`: {
        `vector.dimensions`: 768,
        `vector.similarity_function`: 'cosine'
      }
    }
    
  4. Bind the Store in Laravel In AppServiceProvider.php:

    public function register()
    {
        $this->app->singleton(\Symfony\Component\AI\VectorStoreInterface::class, function ($app) {
            return new \Symfony\Component\AI\Store\Neo4jStore(
                new \Neo4j\ClientBuilder()
                    ->withUri(env('NEO4J_URI'))
                    ->withBasicAuth(env('NEO4J_USERNAME'), env('NEO4J_PASSWORD'))
                    ->build()
            );
        });
    }
    
  5. First Use Case: Basic Similarity Search

    use Symfony\Component\AI\VectorStoreInterface;
    
    $store = app(VectorStoreInterface::class);
    
    // Add embeddings
    $store->add([0.1, 0.2, 0.3, ...]); // Your 768-dim vector
    
    // Search
    $results = $store->similaritySearch([0.11, 0.21, 0.31, ...], 5);
    

Where to Look First

  • Package Docs: Symfony AI Neo4j Store (minimal, but check Symfony AI docs for core concepts).
  • Neo4j Vector Index Docs: Cypher Manual for schema setup.
  • Symfony AI Interface: \Symfony\Component\AI\VectorStoreInterface defines the contract this package implements.

Implementation Patterns

Core Workflows

1. Hybrid RAG Pipeline

// 1. Query Neo4j for graph-aware context
$graphResults = $neo4jClient->run(
    'MATCH (d:Document)-[:RELATED_TO]->(c:Concept)
     WHERE d.category = $category
     RETURN d.embedding AS embedding, d.id AS id',
    ['category' => 'quantum_computing']
);

// 2. Use Symfony AI to search embeddings
$store = app(VectorStoreInterface::class);
$results = $store->similaritySearch($queryEmbedding, 10);

// 3. Merge results (e.g., prioritize graph-connected items)
$merged = collect($results)->merge($graphResults)->unique('id')->values();

2. Filtered Vector Search

Leverage Neo4j’s Cypher filtering:

// Custom query with filters
$results = $store->similaritySearch(
    $queryEmbedding,
    5,
    ['filters' => ['author' => 'Einstein', 'year' => ['>' => 1900]]]
);

// Under the hood, this generates:
/*
MATCH (d:Document)
WHERE vectorSimilarity(d.embedding, $query) > 0.8
AND d.author = 'Einstein'
AND d.year > 1900
RETURN d
ORDER BY vectorSimilarity(d.embedding, $query) DESC
LIMIT 5
*/

3. Bulk Operations

// Batch add embeddings (e.g., from a Laravel collection)
$embeddings = Model::chunk(100, function ($items) {
    $vectors = $items->map(fn ($item) => $item->embedding)->toArray();
    $store->add($vectors);
});

// Batch remove by IDs
$store->remove(['id1', 'id2', 'id3']);

Integration Tips

Laravel Service Wrapper

Create a Laravel-friendly facade to hide Symfony dependencies:

namespace App\Services;

use Symfony\Component\AI\VectorStoreInterface;

class Neo4jVectorStoreService
{
    public function __construct(private VectorStoreInterface $store) {}

    public function findSimilarDocuments(array $embedding, int $limit = 5, array $filters = []): array
    {
        return $this->store->similaritySearch($embedding, $limit, $filters);
    }

    public function addDocument(array $embedding, array $metadata = []): void
    {
        $this->store->add($embedding, $metadata);
    }
}

Event-Driven Updates

Use Laravel events to sync embeddings:

// In a model observer
ModelObserved::created(function ($model) {
    $store = app(Neo4jVectorStoreService::class);
    $store->addDocument($model->embedding, [
        'id' => $model->id,
        'type' => 'document',
        'metadata' => $model->metadata
    ]);
});

Query Optimization

  1. Index Configuration: Tune dimensions/similarity function based on your embeddings:
    CALL db.indexes()
    YIELD name, type, labelsOrTypes, properties, options
    WHERE type = 'SEMANTIC'
    RETURN name, options
    
  2. Batch Queries: Use UNWIND for bulk operations:
    UNWIND $embeddings AS embedding
    CREATE (:Document {embedding: embedding})
    

Hybrid Caching

Cache frequent queries in Redis:

public function cachedSimilaritySearch(array $embedding, int $limit = 5): array
{
    $cacheKey = 'vector_search_' . md5(serialize($embedding));
    return cache()->remember($cacheKey, now()->addHours(1), function () use ($embedding, $limit) {
        return $this->store->similaritySearch($embedding, $limit);
    });
}

Gotchas and Tips

Pitfalls

1. Schema Rigidity

  • Issue: Neo4j schema changes (e.g., adding a new label) require Cypher migrations.
    • Fix: Design flexible labels (e.g., :Content instead of :Document, :Article) and use properties for type discrimination.
  • Example:
    // Bad: Hardcoded label
    CREATE (:Document {embedding: $vector})
    
    // Good: Flexible schema
    CREATE (n:Content {type: 'document', embedding: $vector})
    

2. Vector Dimension Mismatch

  • Issue: Embeddings with incorrect dimensions (e.g., 384 vs. 768) will fail silently or return poor results.
    • Fix: Validate dimensions before insertion:
      public function add(array $embedding, array $metadata = []): void
      {
          if (count($embedding) !== 768) {
              throw new \InvalidArgumentException('Embedding must have 768 dimensions');
          }
          $this->store->add($embedding, $metadata);
      }
      

3. Neo4j Driver Timeouts

  • Issue: Large queries may timeout (default: 30s).
    • Fix: Adjust timeout in the client builder:
      $client = (new \Neo4j\ClientBuilder())
          ->withUri(env('NEO4J_URI'))
          ->withConnectionTimeout(60) // Increase timeout
          ->build();
      

4. Filter Syntax Quirks

  • Issue: Complex filters may not translate correctly to Cypher.
    • Fix: Use raw Cypher for advanced queries:
      $results = $store->similaritySearch($embedding, 5, [
          'rawCypher' => '
              MATCH (d:Document)-[:TAGGED_WITH]->(t:Tag {name: $tag})
              WHERE vectorSimilarity(d.embedding, $query) > 0.8
              RETURN d
              ORDER BY vectorSimilarity(d.embedding, $query) DESC
              LIMIT 5
          ',
          'params' => ['tag' => 'quantum', 'query' => $embedding]
      ]);
      

5. Memory Limits

  • Issue: Loading all embeddings into memory for similarity search.
    • Fix: Use Neo4j’s native vector operations (avoid client-side processing):
      // Good: Server-side similarity
      CALL db.index.vectorQueryNodes('embedding_index', $query, 5)
      
      // Bad: Client-side (avoid)
      MATCH (
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky