A module to implement a RAG (Retrieval-Augmented Generation) compatible database schema for ArcadeDB.
The Arcade::Ragschema module provides a default-index configuration optimized for:
- Vector similarity search (semantic embeddings)
- Metadata filtering
The module is included in the gem and automatically available when you require arcade.
require 'arcade'
module MyApp
class Document < Arcade::Vertex
include Arcade::Ragschema
attribute :content, Types::String
attribute :embedding?, Types::Array.of(Types::Float).optional
attribute :metadata?, Types::Hash.optional
end
end
# Create the database type with RAG indexes
MyApp::Document.create_typemodule MyApp
class Document < Arcade::Vertex
include Arcade::Ragschema
attribute :content, Types::String
attribute :embedding?, Types::Array.of(Types::Float).optional
attribute :title?, Types::String.optional
attribute :metadata?, Types::Hash.optional
def self.db_init
# Custom schema with 768-dimensional embeddings
rag_db_init(vector_dimension: 768)
end
end
end# Generate embedding using your preferred service (OpenAI, HuggingFace, etc.)
embedding = generate_embedding("Your text content here")
doc = MyApp::Document.create(
content: "The content of your document",
embedding: embedding,
metadata: {
author: "John Doe",
tags: ["ruby", "database"],
category: "technical"
},
source_url: "https://example.com/document",
created_at: DateTime.now
)Perform semantic search using vector embeddings:
# Generate embedding for the query
query_embedding = generate_embedding("What is a graph database?")
# Search for similar documents
results = MyApp::Document.vector_search(
query_embedding,
limit: 10, # Maximum number of results
threshold: 0.7 # Minimum similarity score (0.0 to 1.0)
)
results.each do |doc|
puts "#{doc[:content]} (similarity: #{doc[:similarity]})"
endCombine vector similarity with SQL LIKE text filtering:
query_embedding = generate_embedding("graph database")
results = MyApp::Document.hybrid_search(
query_embedding,
"Ruby programming", # SQL LIKE search term
limit: 10,
vector_threshold: 0.7
)You can also call vector_search on an instance (delegates to class method):
doc = MyApp::Document.first
results = doc.vector_search(query_embedding, limit: 5)The RAG schema creates the following properties and indexes:
embedding- ARRAY_OF_FLOATS type for vector storagecontent- STRING for full document contentmetadata- MAP for flexible metadatasource_url- STRING for source trackingcreated_at- DATETIME for timestamp
- LSM_VECTOR index on
embeddingfor similarity search with COSINE similarity - LSM_TREE index on
metadatafor filtering
| Option | Default | Description |
|---|---|---|
vector_dimension |
1536 | Dimension of vector embeddings (OpenAI default) |
| Option | Default | Description |
|---|---|---|
limit |
10 | Maximum number of results to return |
threshold |
0.7 | Minimum similarity score (0.0-1.0) |
| Option | Default | Description |
|---|---|---|
limit |
10 | Maximum number of results |
vector_threshold |
0.7 | Minimum vector similarity score |
Returns the SQL commands for creating RAG indexes.
schema = MyApp::Document.rag_schema(vector_dimension: 768)
# => "CREATE INDEX ON my_document (embedding) LSM_VECTOR METADATA {dimensions: 768, similarity: 'COSINE'}\n..."Returns the SQL commands for creating properties and indexes. This is typically called from db_init.
sql = MyApp::Document.rag_db_init(vector_dimension: 768)Perform vector similarity search across all documents. Returns metadata only (not embedding vectors) for efficiency.
results = MyApp::Document.vector_search(query_embedding, limit: 10, threshold: 0.7)
# Returns: Array of Hashes with :title, :content, :category, :similarity, etc.Perform hybrid search combining vector similarity with SQL LIKE text filtering.
results = MyApp::Document.hybrid_search(query_embedding, "search terms", limit: 10, vector_threshold: 0.7)Instance method that delegates to the class method.
doc = MyApp::Document.first
results = doc.vector_search(query_embedding, limit: 5)Full-text search is not yet implemented. The FULLTEXT index type is not supported in the current ArcadeDB server version.
For text filtering, use the hybrid_search method which uses SQL LIKE pattern matching instead:
# Instead of full-text search, use LIKE-based filtering
results = MyApp::Document.hybrid_search(
query_embedding,
"search term", # Uses: content LIKE '%search term%'
limit: 10
)Future versions may add support for:
- Apache Lucene-based full-text indexes
- Tokenization and stemming
- Relevance scoring
See examples/rag_usecase_demo.rb for a complete working example.
- ArcadeDB server with vector search support (version 23.12+)
- External embedding service (OpenAI, HuggingFace, etc.) for generating embeddings
Run the RAG schema tests:
bundle exec rspec spec/lib/rag_schema_spec.rb
bundle exec rspec spec/lib/usecase/rag_integration_spec.rb