vectra-client 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +77 -37
  3. data/CHANGELOG.md +49 -6
  4. data/README.md +52 -393
  5. data/docs/Gemfile +9 -0
  6. data/docs/_config.yml +37 -0
  7. data/docs/_layouts/default.html +14 -0
  8. data/docs/_layouts/home.html +187 -0
  9. data/docs/_layouts/page.html +82 -0
  10. data/docs/_site/api/overview/index.html +145 -0
  11. data/docs/_site/assets/main.css +649 -0
  12. data/docs/_site/assets/main.css.map +1 -0
  13. data/docs/_site/assets/minima-social-icons.svg +33 -0
  14. data/docs/_site/assets/style.css +295 -0
  15. data/docs/_site/community/contributing/index.html +110 -0
  16. data/docs/_site/examples/basic-usage/index.html +117 -0
  17. data/docs/_site/examples/index.html +58 -0
  18. data/docs/_site/feed.xml +1 -0
  19. data/docs/_site/guides/getting-started/index.html +106 -0
  20. data/docs/_site/guides/installation/index.html +82 -0
  21. data/docs/_site/index.html +92 -0
  22. data/docs/_site/providers/index.html +119 -0
  23. data/docs/_site/providers/pgvector/index.html +155 -0
  24. data/docs/_site/providers/pinecone/index.html +121 -0
  25. data/docs/_site/providers/qdrant/index.html +124 -0
  26. data/docs/_site/providers/weaviate/index.html +123 -0
  27. data/docs/_site/robots.txt +1 -0
  28. data/docs/_site/sitemap.xml +39 -0
  29. data/docs/api/overview.md +126 -0
  30. data/docs/assets/style.css +927 -0
  31. data/docs/community/contributing.md +89 -0
  32. data/docs/examples/basic-usage.md +102 -0
  33. data/docs/examples/index.md +54 -0
  34. data/docs/guides/getting-started.md +90 -0
  35. data/docs/guides/installation.md +67 -0
  36. data/docs/guides/performance.md +200 -0
  37. data/docs/index.md +37 -0
  38. data/docs/providers/index.md +81 -0
  39. data/docs/providers/pgvector.md +95 -0
  40. data/docs/providers/pinecone.md +72 -0
  41. data/docs/providers/qdrant.md +73 -0
  42. data/docs/providers/weaviate.md +72 -0
  43. data/lib/vectra/batch.rb +148 -0
  44. data/lib/vectra/cache.rb +261 -0
  45. data/lib/vectra/configuration.rb +6 -1
  46. data/lib/vectra/pool.rb +256 -0
  47. data/lib/vectra/streaming.rb +153 -0
  48. data/lib/vectra/version.rb +1 -1
  49. data/lib/vectra.rb +4 -0
  50. data/netlify.toml +12 -0
  51. metadata +58 -5
  52. data/IMPLEMENTATION_GUIDE.md +0 -686
  53. data/NEW_FEATURES_v0.2.0.md +0 -459
  54. data/RELEASE_CHECKLIST_v0.2.0.md +0 -383
  55. data/USAGE_EXAMPLES.md +0 -787
@@ -0,0 +1,89 @@
1
+ ---
2
+ layout: page
3
+ title: Contributing
4
+ permalink: /community/contributing/
5
+ ---
6
+
7
+ # Contributing to Vectra
8
+
9
+ We welcome contributions! Here's how to get started.
10
+
11
+ ## Development Setup
12
+
13
+ 1. Clone the repository:
14
+ ```bash
15
+ git clone https://github.com/stokry/vectra.git
16
+ cd vectra
17
+ ```
18
+
19
+ 2. Install dependencies:
20
+ ```bash
21
+ bundle install
22
+ ```
23
+
24
+ 3. Run tests:
25
+ ```bash
26
+ bundle exec rspec
27
+ ```
28
+
29
+ ## Making Changes
30
+
31
+ 1. Create a feature branch:
32
+ ```bash
33
+ git checkout -b feature/your-feature-name
34
+ ```
35
+
36
+ 2. Make your changes and write tests
37
+ 3. Run linter:
38
+ ```bash
39
+ bundle exec rubocop
40
+ ```
41
+
42
+ 4. Commit and push:
43
+ ```bash
44
+ git add .
45
+ git commit -m "Description of changes"
46
+ git push origin feature/your-feature-name
47
+ ```
48
+
49
+ 5. Create a Pull Request
50
+
51
+ ## Code Style
52
+
53
+ We use RuboCop for code style. Ensure your code passes:
54
+
55
+ ```bash
56
+ bundle exec rubocop
57
+ ```
58
+
59
+ ## Testing
60
+
61
+ All changes require tests:
62
+
63
+ ```bash
64
+ # Run all tests
65
+ bundle exec rspec
66
+
67
+ # Run specific suite
68
+ bundle exec rspec spec/vectra
69
+
70
+ # Run with coverage
71
+ bundle exec rspec --cov
72
+ ```
73
+
74
+ ## Documentation
75
+
76
+ Please update documentation for any changes:
77
+
78
+ - Update README.md for user-facing changes
79
+ - Update CHANGELOG.md
80
+ - Add examples if needed
81
+
82
+ ## Questions?
83
+
84
+ Feel free to:
85
+ - Open an issue on GitHub
86
+ - Check existing issues and discussions
87
+ - Read the [Implementation Guide](https://github.com/stokry/vectra/blob/main/IMPLEMENTATION_GUIDE.md)
88
+
89
+ Thank you for contributing! 🙌
@@ -0,0 +1,102 @@
1
+ ---
2
+ layout: page
3
+ title: Basic Usage
4
+ permalink: /examples/basic-usage/
5
+ ---
6
+
7
+ # Basic Usage Examples
8
+
9
+ ## Simple Search
10
+
11
+ ```ruby
12
+ require 'vectra'
13
+
14
+ client = Vectra::Client.new(
15
+ provider: :pinecone,
16
+ api_key: ENV['PINECONE_API_KEY'],
17
+ environment: 'us-west-4'
18
+ )
19
+
20
+ # Search for similar vectors
21
+ results = client.query(
22
+ vector: [0.1, 0.2, 0.3],
23
+ top_k: 5
24
+ )
25
+
26
+ puts results.matches.count
27
+ ```
28
+
29
+ ## Batch Operations
30
+
31
+ ```ruby
32
+ # Upsert multiple vectors at once
33
+ vectors = [
34
+ { id: '1', values: [0.1, 0.2, 0.3], metadata: { title: 'Doc 1' } },
35
+ { id: '2', values: [0.2, 0.3, 0.4], metadata: { title: 'Doc 2' } },
36
+ { id: '3', values: [0.3, 0.4, 0.5], metadata: { title: 'Doc 3' } }
37
+ ]
38
+
39
+ client.upsert(vectors: vectors)
40
+
41
+ # Delete multiple vectors
42
+ client.delete(ids: ['1', '2', '3'])
43
+ ```
44
+
45
+ ## Rails Integration
46
+
47
+ ```ruby
48
+ # config/initializers/vectra.rb
49
+ Vectra.configure do |config|
50
+ config.provider = :pgvector
51
+ config.database = Rails.configuration.database_configuration[Rails.env]['database']
52
+ end
53
+
54
+ # app/models/document.rb
55
+ class Document < ApplicationRecord
56
+ include Vectra::ActiveRecord
57
+
58
+ vector_search :embedding
59
+
60
+ def generate_embedding
61
+ # Generate embedding using OpenAI, Cohere, etc.
62
+ embedding_vector = generate_vector_from_text(content)
63
+ self.embedding = embedding_vector
64
+ end
65
+ end
66
+
67
+ # Usage
68
+ doc = Document.find(1)
69
+ similar_docs = doc.vector_search(limit: 10)
70
+ ```
71
+
72
+ ## With Metadata Filtering
73
+
74
+ ```ruby
75
+ results = client.query(
76
+ vector: [0.1, 0.2, 0.3],
77
+ top_k: 10,
78
+ include_metadata: true
79
+ )
80
+
81
+ results.matches.each do |match|
82
+ puts "ID: #{match['id']}"
83
+ puts "Score: #{match['score']}"
84
+ puts "Metadata: #{match['metadata']}"
85
+ end
86
+ ```
87
+
88
+ ## Error Handling
89
+
90
+ ```ruby
91
+ begin
92
+ client.query(vector: [0.1, 0.2, 0.3])
93
+ rescue Vectra::ConnectionError => e
94
+ puts "Connection failed: #{e.message}"
95
+ rescue Vectra::ValidationError => e
96
+ puts "Invalid input: #{e.message}"
97
+ rescue => e
98
+ puts "Unexpected error: #{e.message}"
99
+ end
100
+ ```
101
+
102
+ See [Getting Started]({{ site.baseurl }}/guides/getting-started) for more examples.
@@ -0,0 +1,54 @@
1
+ ---
2
+ layout: page
3
+ title: Examples
4
+ permalink: /examples/
5
+ ---
6
+
7
+ # Code Examples
8
+
9
+ Practical examples to get started with Vectra.
10
+
11
+ ## Quick Examples
12
+
13
+ <div class="tma-comparison-grid">
14
+ <div class="tma-comparison-card">
15
+ <h4>Basic Usage</h4>
16
+ <p>Simple searches and CRUD operations</p>
17
+ <a href="{{ site.baseurl }}/examples/basic-usage/">View Guide →</a>
18
+ </div>
19
+ <div class="tma-comparison-card">
20
+ <h4>Rails Integration</h4>
21
+ <p>ActiveRecord integration with has_vector</p>
22
+ <a href="{{ site.baseurl }}/providers/pgvector/">View Guide →</a>
23
+ </div>
24
+ </div>
25
+
26
+ ## Provider Examples
27
+
28
+ <div class="tma-comparison-grid">
29
+ <div class="tma-comparison-card">
30
+ <h4>Pinecone</h4>
31
+ <p>Managed cloud vector database</p>
32
+ <a href="{{ site.baseurl }}/providers/pinecone/">View Guide →</a>
33
+ </div>
34
+ <div class="tma-comparison-card">
35
+ <h4>Qdrant</h4>
36
+ <p>Open source, self-hosted</p>
37
+ <a href="{{ site.baseurl }}/providers/qdrant/">View Guide →</a>
38
+ </div>
39
+ <div class="tma-comparison-card">
40
+ <h4>Weaviate</h4>
41
+ <p>Semantic search with GraphQL</p>
42
+ <a href="{{ site.baseurl }}/providers/weaviate/">View Guide →</a>
43
+ </div>
44
+ <div class="tma-comparison-card">
45
+ <h4>pgvector</h4>
46
+ <p>PostgreSQL with vector support</p>
47
+ <a href="{{ site.baseurl }}/providers/pgvector/">View Guide →</a>
48
+ </div>
49
+ </div>
50
+
51
+ ## More Resources
52
+
53
+ - [GitHub Examples](https://github.com/stokry/vectra/tree/main/examples) - Full example files
54
+ - [Integration Tests](https://github.com/stokry/vectra/tree/main/spec/integration) - Real-world test cases
@@ -0,0 +1,90 @@
1
+ ---
2
+ layout: page
3
+ title: Getting Started
4
+ permalink: /guides/getting-started/
5
+ ---
6
+
7
+ # Getting Started with Vectra
8
+
9
+ ## Initialize a Client
10
+
11
+ ```ruby
12
+ require 'vectra'
13
+
14
+ # Initialize with Pinecone
15
+ client = Vectra::Client.new(
16
+ provider: :pinecone,
17
+ api_key: ENV['PINECONE_API_KEY'],
18
+ environment: 'us-west-4'
19
+ )
20
+ ```
21
+
22
+ ## Basic Operations
23
+
24
+ ### Upsert Vectors
25
+
26
+ ```ruby
27
+ client.upsert(
28
+ vectors: [
29
+ {
30
+ id: 'vec-1',
31
+ values: [0.1, 0.2, 0.3],
32
+ metadata: { title: 'Document 1' }
33
+ },
34
+ {
35
+ id: 'vec-2',
36
+ values: [0.2, 0.3, 0.4],
37
+ metadata: { title: 'Document 2' }
38
+ }
39
+ ]
40
+ )
41
+ ```
42
+
43
+ ### Query (Search)
44
+
45
+ ```ruby
46
+ results = client.query(
47
+ vector: [0.1, 0.2, 0.3],
48
+ top_k: 5,
49
+ include_metadata: true
50
+ )
51
+
52
+ results.matches.each do |match|
53
+ puts "ID: #{match['id']}, Score: #{match['score']}"
54
+ end
55
+ ```
56
+
57
+ ### Delete Vectors
58
+
59
+ ```ruby
60
+ client.delete(ids: ['vec-1', 'vec-2'])
61
+ ```
62
+
63
+ ### Get Vector Stats
64
+
65
+ ```ruby
66
+ stats = client.stats
67
+ puts "Index dimension: #{stats['dimension']}"
68
+ puts "Vector count: #{stats['vector_count']}"
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ Create a configuration file (Rails: `config/initializers/vectra.rb`):
74
+
75
+ ```ruby
76
+ Vectra.configure do |config|
77
+ config.provider = :pinecone
78
+ config.api_key = ENV['PINECONE_API_KEY']
79
+ config.environment = 'us-west-4'
80
+ end
81
+
82
+ # Later in your code:
83
+ client = Vectra::Client.new
84
+ ```
85
+
86
+ ## Next Steps
87
+
88
+ - [API Reference]({{ site.baseurl }}/api/overview)
89
+ - [Provider Guides]({{ site.baseurl }}/providers)
90
+ - [Examples]({{ site.baseurl }}/examples/basic-usage)
@@ -0,0 +1,67 @@
1
+ ---
2
+ layout: page
3
+ title: Installation
4
+ permalink: /guides/installation/
5
+ ---
6
+
7
+ # Installation Guide
8
+
9
+ ## Requirements
10
+
11
+ - Ruby 3.2.0 or higher
12
+ - Bundler
13
+
14
+ ## Install via Bundler
15
+
16
+ Add Vectra to your Gemfile:
17
+
18
+ ```ruby
19
+ gem 'vectra-client'
20
+ ```
21
+
22
+ Then run:
23
+
24
+ ```bash
25
+ bundle install
26
+ ```
27
+
28
+ ## Install Standalone
29
+
30
+ Alternatively, install via RubyGems:
31
+
32
+ ```bash
33
+ gem install vectra-client
34
+ ```
35
+
36
+ ## Rails Integration
37
+
38
+ For Rails applications, run the install generator:
39
+
40
+ ```bash
41
+ rails generate vectra:install
42
+ ```
43
+
44
+ This will create an initializer file at `config/initializers/vectra.rb`.
45
+
46
+ ## Provider-Specific Setup
47
+
48
+ Each vector database provider may require additional dependencies:
49
+
50
+ ### PostgreSQL with pgvector
51
+ ```ruby
52
+ gem 'pg', '~> 1.5'
53
+ ```
54
+
55
+ ### Instrumentation
56
+
57
+ #### Datadog
58
+ ```ruby
59
+ gem 'dogstatsd-ruby'
60
+ ```
61
+
62
+ #### New Relic
63
+ ```ruby
64
+ gem 'newrelic_rpm'
65
+ ```
66
+
67
+ See [Provider Guides]({{ site.baseurl }}/providers) for detailed setup instructions.
@@ -0,0 +1,200 @@
1
+ ---
2
+ layout: page
3
+ title: Performance & Optimization
4
+ permalink: /guides/performance/
5
+ ---
6
+
7
+ # Performance & Optimization
8
+
9
+ Vectra provides several performance optimization features for high-throughput applications.
10
+
11
+ ## Async Batch Operations
12
+
13
+ Process large vector sets concurrently with automatic chunking:
14
+
15
+ ```ruby
16
+ require 'vectra'
17
+
18
+ client = Vectra::Client.new(provider: :pinecone, api_key: ENV['PINECONE_API_KEY'])
19
+
20
+ # Create a batch processor with 4 concurrent workers
21
+ batch = Vectra::Batch.new(client, concurrency: 4)
22
+
23
+ # Async upsert with automatic chunking
24
+ vectors = 10_000.times.map { |i| { id: "vec_#{i}", values: Array.new(384) { rand } } }
25
+
26
+ result = batch.upsert_async(
27
+ index: 'my-index',
28
+ vectors: vectors,
29
+ chunk_size: 100
30
+ )
31
+
32
+ puts "Upserted: #{result[:upserted_count]} vectors in #{result[:chunks]} chunks"
33
+ puts "Errors: #{result[:errors].size}" if result[:errors].any?
34
+ ```
35
+
36
+ ### Batch Delete
37
+
38
+ ```ruby
39
+ ids = 1000.times.map { |i| "vec_#{i}" }
40
+
41
+ result = batch.delete_async(
42
+ index: 'my-index',
43
+ ids: ids,
44
+ chunk_size: 100
45
+ )
46
+ ```
47
+
48
+ ### Batch Fetch
49
+
50
+ ```ruby
51
+ ids = ['vec_1', 'vec_2', 'vec_3']
52
+
53
+ vectors = batch.fetch_async(
54
+ index: 'my-index',
55
+ ids: ids,
56
+ chunk_size: 50
57
+ )
58
+ ```
59
+
60
+ ## Streaming Results
61
+
62
+ For large query result sets, use streaming to reduce memory usage:
63
+
64
+ ```ruby
65
+ stream = Vectra::Streaming.new(client, page_size: 100)
66
+
67
+ # Stream with a block
68
+ stream.query_each(
69
+ index: 'my-index',
70
+ vector: query_vector,
71
+ total: 1000
72
+ ) do |match|
73
+ process_match(match)
74
+ end
75
+
76
+ # Or use lazy enumerator
77
+ results = stream.query_stream(
78
+ index: 'my-index',
79
+ vector: query_vector,
80
+ total: 1000
81
+ )
82
+
83
+ # Only fetches what you need
84
+ results.take(50).each { |m| puts m.id }
85
+ ```
86
+
87
+ ## Caching Layer
88
+
89
+ Cache frequently queried vectors to reduce database load:
90
+
91
+ ```ruby
92
+ # Create cache with 5-minute TTL
93
+ cache = Vectra::Cache.new(ttl: 300, max_size: 1000)
94
+
95
+ # Wrap client with caching
96
+ cached_client = Vectra::CachedClient.new(client, cache: cache)
97
+
98
+ # First query hits the database
99
+ result1 = cached_client.query(index: 'idx', vector: vec, top_k: 10)
100
+
101
+ # Second identical query returns cached result
102
+ result2 = cached_client.query(index: 'idx', vector: vec, top_k: 10)
103
+
104
+ # Invalidate cache when data changes
105
+ cached_client.invalidate_index('idx')
106
+
107
+ # Clear all cache
108
+ cached_client.clear_cache
109
+ ```
110
+
111
+ ### Cache Statistics
112
+
113
+ ```ruby
114
+ stats = cache.stats
115
+ puts "Cache size: #{stats[:size]}/#{stats[:max_size]}"
116
+ puts "TTL: #{stats[:ttl]} seconds"
117
+ ```
118
+
119
+ ## Connection Pooling (pgvector)
120
+
121
+ For pgvector, use connection pooling with warmup:
122
+
123
+ ```ruby
124
+ # Configure pool size
125
+ Vectra.configure do |config|
126
+ config.provider = :pgvector
127
+ config.host = ENV['DATABASE_URL']
128
+ config.pool_size = 10
129
+ config.pool_timeout = 5
130
+ end
131
+
132
+ client = Vectra::Client.new
133
+
134
+ # Warmup connections at startup
135
+ client.provider.warmup_pool(5)
136
+
137
+ # Check pool stats
138
+ stats = client.provider.pool_stats
139
+ puts "Available connections: #{stats[:available]}"
140
+ puts "Checked out: #{stats[:checked_out]}"
141
+
142
+ # Shutdown pool when done
143
+ client.provider.shutdown_pool
144
+ ```
145
+
146
+ ## Configuration Options
147
+
148
+ ```ruby
149
+ Vectra.configure do |config|
150
+ # Provider settings
151
+ config.provider = :pinecone
152
+ config.api_key = ENV['PINECONE_API_KEY']
153
+
154
+ # Timeouts
155
+ config.timeout = 30
156
+ config.open_timeout = 10
157
+
158
+ # Retry settings
159
+ config.max_retries = 3
160
+ config.retry_delay = 1
161
+
162
+ # Batch operations
163
+ config.batch_size = 100
164
+ config.async_concurrency = 4
165
+
166
+ # Connection pooling (pgvector)
167
+ config.pool_size = 10
168
+ config.pool_timeout = 5
169
+
170
+ # Caching
171
+ config.cache_enabled = true
172
+ config.cache_ttl = 300
173
+ config.cache_max_size = 1000
174
+ end
175
+ ```
176
+
177
+ ## Benchmarking
178
+
179
+ Run the included benchmarks:
180
+
181
+ ```bash
182
+ # Batch operations benchmark
183
+ bundle exec ruby benchmarks/batch_operations_benchmark.rb
184
+
185
+ # Connection pooling benchmark
186
+ bundle exec ruby benchmarks/connection_pooling_benchmark.rb
187
+ ```
188
+
189
+ ## Best Practices
190
+
191
+ 1. **Batch Size**: Use batch sizes of 100-500 for optimal throughput
192
+ 2. **Concurrency**: Set concurrency to 2-4x your CPU cores
193
+ 3. **Connection Pool**: Size pool to expected concurrent requests + 20%
194
+ 4. **Cache TTL**: Set TTL based on data freshness requirements
195
+ 5. **Warmup**: Always warmup connections in production
196
+
197
+ ## Next Steps
198
+
199
+ - [API Reference]({{ site.baseurl }}/api/overview)
200
+ - [Provider Guides]({{ site.baseurl }}/providers)
data/docs/index.md ADDED
@@ -0,0 +1,37 @@
1
+ ---
2
+ layout: home
3
+ title: Vectra
4
+ ---
5
+
6
+ ```ruby
7
+ require 'vectra'
8
+
9
+ # Initialize any provider with the same API
10
+ client = Vectra::Client.new(
11
+ provider: :pinecone, # or :qdrant, :weaviate, :pgvector
12
+ api_key: ENV['API_KEY'],
13
+ host: 'your-host.example.com'
14
+ )
15
+
16
+ # Store vectors with metadata
17
+ client.upsert(
18
+ vectors: [
19
+ {
20
+ id: 'doc-1',
21
+ values: [0.1, 0.2, 0.3, ...], # Your embedding
22
+ metadata: { title: 'Getting Started with AI' }
23
+ }
24
+ ]
25
+ )
26
+
27
+ # Search by similarity
28
+ results = client.query(
29
+ vector: [0.1, 0.2, 0.3, ...],
30
+ top_k: 10,
31
+ filter: { category: 'tutorials' }
32
+ )
33
+
34
+ results.each do |match|
35
+ puts "#{match['id']}: #{match['score']}"
36
+ end
37
+ ```
@@ -0,0 +1,81 @@
1
+ ---
2
+ layout: page
3
+ title: Providers
4
+ permalink: /providers/
5
+ ---
6
+
7
+ # Vector Database Providers
8
+
9
+ Vectra supports multiple vector database providers. Choose the one that best fits your needs.
10
+
11
+ ## Supported Providers
12
+
13
+ | Provider | Type | Best For |
14
+ |----------|------|----------|
15
+ | [**Pinecone**]({{ site.baseurl }}/providers/pinecone) | Managed Cloud | Production, Zero ops |
16
+ | [**Qdrant**]({{ site.baseurl }}/providers/qdrant) | Open Source | Self-hosted, Performance |
17
+ | [**Weaviate**]({{ site.baseurl }}/providers/weaviate) | Open Source | Semantic search, GraphQL |
18
+ | [**pgvector**]({{ site.baseurl }}/providers/pgvector) | PostgreSQL | SQL integration, ACID |
19
+
20
+ ## Quick Comparison
21
+
22
+ <div class="tma-comparison-grid">
23
+ <div class="tma-comparison-card">
24
+ <h4>Pinecone</h4>
25
+ <ul>
26
+ <li class="pro">Fully managed service</li>
27
+ <li class="pro">Easy setup</li>
28
+ <li class="pro">Highly scalable</li>
29
+ <li class="con">Cloud only</li>
30
+ <li class="con">Paid service</li>
31
+ </ul>
32
+ </div>
33
+ <div class="tma-comparison-card">
34
+ <h4>Qdrant</h4>
35
+ <ul>
36
+ <li class="pro">Open source</li>
37
+ <li class="pro">Self-hosted option</li>
38
+ <li class="pro">High performance</li>
39
+ <li class="pro">Cloud option available</li>
40
+ <li class="con">More configuration</li>
41
+ </ul>
42
+ </div>
43
+ <div class="tma-comparison-card">
44
+ <h4>Weaviate</h4>
45
+ <ul>
46
+ <li class="pro">Open source</li>
47
+ <li class="pro">Semantic search</li>
48
+ <li class="pro">GraphQL API</li>
49
+ <li class="pro">Multi-model support</li>
50
+ <li class="con">More complex setup</li>
51
+ </ul>
52
+ </div>
53
+ <div class="tma-comparison-card">
54
+ <h4>pgvector</h4>
55
+ <ul>
56
+ <li class="pro">SQL database</li>
57
+ <li class="pro">ACID transactions</li>
58
+ <li class="pro">Use existing Postgres</li>
59
+ <li class="pro">Very affordable</li>
60
+ <li class="con">Not vector-specialized</li>
61
+ </ul>
62
+ </div>
63
+ </div>
64
+
65
+ ## Switching Providers
66
+
67
+ One of Vectra's key features is easy provider switching:
68
+
69
+ ```ruby
70
+ # Just change the provider - your code stays the same!
71
+ client = Vectra::Client.new(provider: :qdrant, host: 'localhost:6333')
72
+
73
+ # All operations work identically
74
+ client.upsert(vectors: [...])
75
+ results = client.query(vector: [...], top_k: 5)
76
+ ```
77
+
78
+ ## Next Steps
79
+
80
+ - [Getting Started Guide]({{ site.baseurl }}/guides/getting-started)
81
+ - [API Reference]({{ site.baseurl }}/api/overview)