CURRENT TREND INSIGHT
Chunking strategies and metadata parsing for complex structured PDFs Illustration

Chunking strategies and metadata parsing for complex structured PDFs

Direct Summary:

Complex structured PDFs (contracts, technical manuals, tables-heavy reports) break naive "split every N tokens" chunking because it cuts across headers, tables, and sections without any awareness of document structure. The fix is structure-aware parsing — using a library like Unstructured to detect real document elements (titles, tables, list items) first, and only falling back to plain text-splitting for elements too large to keep whole.

"The future belongs to those who prepare for it today."

— Malcolm X

Key Insights

  • Parse structure before you chunk: a naive fixed-size splitter has no idea where a table ends and a paragraph begins — it will happily cut a table row in half. Structure-aware parsing detects real elements first.
  • Metadata is part of the payload: page number, section title, and element type (table vs. narrative text) should travel with each chunk — they're what let you cite a source or filter results by document section later.
  • Fixed-size splitting is still the fallback: even structure-aware tools resort to plain text-splitting when a single detected element (a long paragraph) exceeds your target chunk size — the two techniques work together, not instead of each other.

A PDF isn't really "text with a fixed size" — it's titles, paragraphs, tables, and list items laid out on a page, and a chunker that ignores that structure will regularly slice a table in half or merge a footer into the middle of a paragraph. The Unstructured library handles this by first detecting document elements (title, narrative text, table, list item) with real metadata — page number, coordinates, element type — and only chunking within or across those elements afterward.

A structure-aware chunking pipeline

1. Partition the document into elements first. Unstructured's partition_pdf function returns a list of typed elements (titles, tables, narrative text) instead of one undifferentiated text blob.

2. Chunk by element boundaries, not raw character counts. Combine small consecutive elements up to your target chunk size, but never split a table element in the middle — tables should stay intact or be summarized as a unit.

3. Carry metadata through to the vector store. Page number and element type should be stored alongside the chunk's text, so a later query can filter to "just tables" or cite the exact page a claim came from.

structured_pdf_chunking.py
# Structure-aware PDF parsing and chunking with Unstructured
from unstructured.partition.pdf import partition_pdf
from unstructured.chunking.title import chunk_by_title

# 1. Partition into typed elements (Title, NarrativeText, Table, ...)
elements = partition_pdf(filename="quarterly_report.pdf")

# 2. Chunk by title boundaries, respecting table/element structure
chunks = chunk_by_title(elements, max_characters=1000)

for chunk in chunks:
    # Each chunk carries page number and element metadata
    print(chunk.metadata.page_number, chunk.text[:80])
Chunking approach Handles tables correctly? Carries page/section metadata?
Fixed-size text splitting No — splits mid-table No — plain text only
Structure-aware (Unstructured) Yes — tables kept as units Yes — page number, element type attached

The metadata is what makes this worth the extra setup — once every chunk carries its page number and element type, your RAG system can cite "page 14, table 2" instead of just returning a wall of retrieved text with no provenance.

Practical Challenge

Take a PDF with at least one table, partition it with Unstructured, and print out the element type of each detected chunk to confirm the table was kept intact rather than split.

Concept Check

Why does structure-aware chunking handle a table in a PDF better than fixed-size text splitting?
Correct! By parsing document structure before chunking, tools like Unstructured know where a table starts and ends, so the chunker can treat it as one unit instead of cutting it at an arbitrary character count.
Incorrect. Try again! Hint: the fix happens at the parsing stage — detecting what kind of element a piece of the page actually is before deciding how to chunk it.

Sources & Further Reading

Previous Guide Dashboard Next Guide