Architecture Series

Unstructured Data & Vector Embeddings in Modern Data Pipelines

How to handle unstructured data (text, images, audio, video) in data pipelines — from ingestion and processing to vector embeddings, vector databases, and RAG architectures for AI applications.

For decades, data platforms focused almost exclusively on structured data — rows and columns in relational tables. But 80–90% of enterprise data is unstructured: emails, documents, call recordings, product images, sensor readings, social media posts, and PDFs.

The rise of Large Language Models (LLMs) and embedding models has given us a new way to work with this data — vector embeddings — and opened entirely new architectural patterns for AI-powered applications.


Types of Unstructured Data

TypeExamplesChallenges
TextDocuments, emails, chat logs, PDFs, contractsVariable length, language variation, entity extraction
ImagesProduct photos, scans, satellite imagery, medical scansHigh storage cost, no inherent structure, format variety
AudioCall recordings, podcasts, voice commandsRequires transcription; language, accent variation
VideoCCTV, training recordings, product demosVery high storage; temporal dimension; frame extraction
Sensor / IoTTemperature readings, accelerometer data, GPS tracesHigh frequency, missing values, noise
LogsApplication logs, access logs, error tracesSemi-structured (structured fields + free-text messages)

Processing Unstructured Data: The Pipeline

Stage 1: Ingestion

Unstructured data lands in the Bronze zone of a data lake in its original format:

Documents (PDF/Word) → ADLS/S3 container (raw/)
Images (JPEG/PNG)   → ADLS/S3 container (raw/)
Audio (WAV/MP3)     → ADLS/S3 container (raw/)

Use object storage metadata tags for organisation:

  • content_type: application/pdf
  • source_system: contracts_crm
  • ingestion_date: 2025-09-19

Stage 2: Extraction & Pre-processing

Convert unstructured files into machine-processable representations:

Data TypeProcessingOutput
PDF / WordApache Tika, Azure Document Intelligence, PDFMinerExtracted text + layout
ImagesAzure Computer Vision, AWS Rekognition, OpenCVCaption, tags, OCR text, object bounding boxes
AudioAzure Speech-to-Text, OpenAI Whisper, AWS TranscribeTranscription + speaker diarisation
VideoAzure Video Indexer, FFmpeg (frame extraction)Transcription + keyframe images

Stage 3: Chunking (for Text)

Long documents must be split into chunks before embedding — embedding models have token limits (typically 512–8192 tokens):

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,        # tokens per chunk
    chunk_overlap=50,      # overlap for context continuity
    separators=["\n\n", "\n", " ", ""]
)
chunks = splitter.split_text(document_text)

Chunking strategies:

  • Fixed-size: simple, uniform chunk sizes
  • Sentence-aware: split at sentence boundaries to preserve semantic units
  • Paragraph-aware: split at natural document section breaks
  • Semantic chunking: use an embedding model to detect when topic shifts (advanced)

Vector Embeddings

A vector embedding is a numerical representation of content — a list of floating-point numbers (typically 768 to 4096 dimensions) that encode the semantic meaning of the content.

"The Eiffel Tower is in Paris"  →  [0.23, -0.17, 0.89, 0.04, ...]  (768 numbers)
"La Tour Eiffel est à Paris"    →  [0.24, -0.16, 0.87, 0.05, ...]  (very similar!)
"Apple stock rose 5% today"     →  [0.91, 0.03, -0.44, 0.76, ...]  (very different)

Key property: semantically similar content has similar vectors (high cosine similarity). This enables similarity search — finding documents “about the same thing” without exact keyword matching.

Embedding Models

ModelProviderDimensionsBest For
text-embedding-3-smallOpenAI1536General English text
text-embedding-3-largeOpenAI3072High-accuracy retrieval
text-embedding-ada-002OpenAI1536Legacy OpenAI workloads
embed-english-v3.0Cohere1024English enterprise text
embed-multilingual-v3.0Cohere1024100+ languages
bge-large-en-v1.5BAAI (OSS)1024Open-source, high performance
all-MiniLM-L6-v2Sentence Transformers (OSS)384Lightweight, fast
CLIPOpenAI (OSS)512Images + text (multi-modal)
from openai import OpenAI

client = OpenAI()
response = client.embeddings.create(
    model="text-embedding-3-small",
    input="What is the return policy for damaged goods?"
)
embedding = response.data[0].embedding  # list of 1536 floats

Vector Databases

A vector database is optimised for storing embeddings and performing fast approximate nearest neighbour (ANN) search — finding the most similar vectors to a query vector.

How Vector Search Works

Query: "What are the refund policies?"
Embed query using same model  →  [0.34, -0.22, 0.78, ...]
Find K nearest vectors in database (cosine/dot-product similarity)
Return top-K most semantically similar chunks
   [1] "Returns accepted within 30 days with receipt..." (similarity: 0.94)
   [2] "For damaged items, refunds are processed in..."  (similarity: 0.91)
   [3] "Store credit issued for all returns over $50..." (similarity: 0.87)

ANN Algorithms

AlgorithmDescriptionTrade-off
HNSW (Hierarchical Navigable Small World)Graph-based; excellent recall/speed balanceHigh memory usage
IVF (Inverted File Index)Cluster-based; good for very large datasetsLower recall than HNSW
PQ (Product Quantisation)Compress vectors for memory efficiencyLower accuracy
DiskANNDisk-based ANN; minimises RAM requirementsSlower than in-memory

Vector Database Options

DatabaseTypeKey Feature
PineconeManaged cloudFully serverless; production-grade SLA
WeaviateOSS + CloudMulti-modal; GraphQL API; hybrid search
QdrantOSS + CloudRust-based; payload filtering; fast
ChromaOSSSimple Python API; great for prototyping
Azure AI SearchManaged cloudHybrid (keyword + vector); native Azure integration
pgvectorPostgreSQL extensionKeep vectors in existing Postgres; no new infra
Databricks Vector SearchManaged on DatabricksNative Unity Catalog integration; Delta sync
Redis StackIn-memory + persistentUltra-low latency; existing Redis infrastructure

RAG: Retrieval-Augmented Generation

RAG (Retrieval-Augmented Generation) is the dominant architecture for building LLM-powered applications that answer questions using your private data.

The Problem RAG Solves

LLMs are trained on public internet data up to a knowledge cutoff. They don’t know:

  • Your company’s internal policies
  • Your product documentation
  • Your customer service history
  • Your proprietary research

RAG solves this by retrieving relevant context from your private knowledge base and injecting it into the LLM prompt at query time.

RAG Architecture

                    ┌─────────────────────────────────────────────┐
INDEXING (offline)  │                                             │
                    │  Documents → Chunk → Embed → Vector Store   │
                    │                                             │
                    └─────────────────────────────────────────────┘

QUERYING (online)
User Question
     ├──1. Embed question using same embedding model
     ├──2. Query vector store for top-K similar chunks
     ├──3. Build prompt:
     │       "Context: {retrieved chunks}\n\nQuestion: {user question}\nAnswer:"
     ├──4. Send to LLM (GPT-4, Claude, Gemini, Llama)
     └──5. Return grounded, cited answer to user

Advanced RAG Patterns

Hybrid Search: combine vector similarity search with traditional BM25 keyword search for better recall:

# Azure AI Search: hybrid query
results = search_client.search(
    search_text="refund policy",          # BM25 keyword
    vector_queries=[VectorizedQuery(       # vector similarity
        vector=query_embedding,
        k_nearest_neighbors=5,
        fields="content_vector"
    )],
    query_type="semantic"
)

Re-ranking: use a cross-encoder model to re-score the top-K retrieved chunks for more accurate relevance ordering before passing to the LLM.

Multi-hop Retrieval: for complex questions requiring multiple facts, retrieve → generate sub-queries → retrieve again — iterating until sufficient context is gathered.


Integrating Unstructured Data into Your Data Platform

In a Lakehouse (Databricks)

# Store raw files in Unity Catalog volumes (Bronze)
# spark reads PDFs, extracts text, chunks it, embeds it

from databricks.sdk import WorkspaceClient

w = WorkspaceClient()
# Use Databricks Vector Search with Unity Catalog integration
# Delta table → auto-sync to vector search index

index = w.vector_search_indexes.create(
    name="catalog.schema.policy_index",
    endpoint_name="my_endpoint",
    primary_key="id",
    embedding_source_column="text_chunk",
    embedding_model_endpoint_name="databricks-bge-large-en"
)

In Microsoft Fabric

  • Store documents in OneLake (ADLS Gen2 via OneLake volumes)
  • Use Azure AI Document Intelligence for extraction (connected to Fabric via Data Factory)
  • Embed with Azure OpenAI (text-embedding-3-small)
  • Store vectors in Azure AI Search (hybrid search over OneLake content)
  • Serve via Fabric Eventhouse (KQL) for vector + metadata queries

When to Add Unstructured Data to Your Platform

Good fit when:

  • You have significant volumes of documents, emails, or records that contain business-critical information not captured in structured databases
  • AI-powered search, Q&A, or summarisation is a key business use case
  • Regulatory compliance requires analysis of communications, contracts, or filings
  • You are building LLM-powered products that need to answer questions from private knowledge

Wait when:

  • Your structured analytics foundation is immature — get that right first
  • You don’t have a clear use case driving unstructured data investment
  • Your team lacks ML/AI engineering capability to operate embedding pipelines and vector indexes