Weaviate Vector Store Integration for AI in Mobile Applications
Weaviate is an open-source vector database with GraphQL and REST API, built-in modules for automatic embedding creation and semantic search. Unlike Pinecone, it supports self-hosting, richer object schemas, and native hybrid search out of the box.
Key Differences from Other Vector Databases
In Weaviate, data is stored as objects with types (classes) — closer to a document database than a pure vector store. Each object has a schema, properties, and a vector.
# Creating a class in Weaviate
client.schema.create_class({
"class": "Document",
"vectorizer": "text2vec-openai", # auto-embeddings on write
"moduleConfig": {
"text2vec-openai": {
"model": "text-embedding-3-small",
"dimensions": 1536
}
},
"properties": [
{"name": "content", "dataType": ["text"]},
{"name": "source", "dataType": ["text"]},
{"name": "userId", "dataType": ["text"]},
{"name": "language", "dataType": ["text"]}
]
})
The text2vec-openai module means Weaviate creates the embedding automatically when adding an object. No need to call Embeddings API separately before upsert. Convenient, but requires passing OpenAI key to Weaviate config.
Hybrid Search: BM25 + Vector Search in One Query
Weaviate's main advantage is native hybrid search. Combines keyword search (BM25) and semantic search through the alpha parameter:
{
Get {
Document(
hybrid: {
query: "password reset",
alpha: 0.75 # 0 = BM25 only, 1 = vector only
}
where: {
path: ["userId"]
operator: Equal
valueText: "user_42"
}
limit: 5
) {
content
source
_additional { score explainScore }
}
}
}
alpha: 0.75 — 75% weight for vector search, 25% for BM25. Optimal value depends on corpus, but 0.7–0.8 works well for most cases.
This is what requires combining two queries in pgvector. In Weaviate — one call.
Self-hosted Weaviate for Private Data
If data cannot go to cloud — Weaviate deploys in Docker:
# docker-compose.yml
services:
weaviate:
image: semitechnologies/weaviate:1.24.0
ports:
- "8080:8080"
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none' # create embeddings ourselves
CLUSTER_HOSTNAME: 'node1'
volumes:
- weaviate_data:/var/lib/weaviate
With self-hosting, you generate embeddings on your backend (local model or API) and pass the vector explicitly when adding an object.
Mobile Client and Multi-tenancy
Weaviate 1.20+ supports native multi-tenancy via tenants. More performant than filtering by userId:
# Create tenant (once during user registration)
client.schema.add_class_tenants("Document", [{"name": f"user_{user_id}"}])
# Add object to user's tenant
client.data_object.create(
data_object={"content": chunk, "source": filename},
class_name="Document",
tenant=f"user_{user_id}",
vector=embedding # if vectorizer = none
)
# Search in user's tenant
result = client.query.get("Document", ["content", "source"]) \
.with_hybrid(query=user_query, alpha=0.75) \
.with_tenant(f"user_{user_id}") \
.with_limit(5) \
.do()
With multi-tenancy enabled, each tenant is stored in a separate shard — search doesn't slow down as user count grows.
Clients and Backend
Weaviate provides official clients for Python, TypeScript, Java, Go. Mobile apps only make HTTP requests to your backend, not directly to Weaviate (same security reasons as with Pinecone).
Node.js/TypeScript backend:
import weaviate, { WeaviateClient } from 'weaviate-ts-client';
const client: WeaviateClient = weaviate.client({
scheme: 'http',
host: 'localhost:8080',
});
// Search — called from REST endpoint for mobile client
async function search(query: string, userId: string) {
return client.graphql.get()
.withClassName('Document')
.withHybrid({ query, alpha: 0.75 })
.withTenant(`user_${userId}`)
.withLimit(5)
.withFields('content source _additional { score }')
.do();
}
Implementation Timeline
Deploy Weaviate (cloud or self-hosted) → create schema with proper types → configure multi-tenancy → ingestion pipeline → backend API for search → mobile UI for results → load testing → monitoring.
Integrating Weaviate on existing backend — 2–3 weeks. From scratch, self-hosted, with mobile client and UI — 4–6 weeks.







