Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quickstart

1. Ingest a folder

fluree doc ingest ./contracts -l contracts
ingest 3 document(s) → contracts
  parser     fluree-doc-parse 407daa0
  escalation none — deterministic tier only; set [doc.vlm] to read scanned pages
  embedding  none — set [doc.embedding] to enable vector search
→ created ledger contracts
  ✓ msa-2024.pdf  parsed: 41p, 512 elements, 138 chunks  t=1
  ✓ nda.docx  parsed: 19 elements, 4 chunks  t=2
  ✓ sow/q3.pdf  parsed: 12p, 96 elements, 27 chunks  t=3
  + full-text index contracts-text:main: 169 chunk(s), 1631 terms

done: 3 ingested, 0 unchanged, 0 failed — 169 chunks, 53 pages, 0 crop(s) read, 0 parse(s) from cache, 6.1s

The ledger was created, each document landed as one commit, and a full-text index was built over the chunks. Two lines say what is not configured yet: no vision model, so scanned pages would stay unread, and no embedding model, so there is nothing to search by meaning.

2. Search it

fluree doc search "termination notice period" -l contracts -n 3
 1. 12.687  msa-2024.pdf  Master Services Agreement / 12. Term and Termination
    Either party may terminate this Agreement for convenience on ninety (90) days' written notice…
    urn:fluree:doc:msa-2024.pdf/chunk/97
 2. 6.801   nda.docx  Term
    This Agreement terminates two years after the Effective Date unless…
    urn:fluree:doc:nda.docx/chunk/2
(2 result(s), text, 41 ms)

Each hit is a score, the file, the section path the chunk sits under, a snippet, and the chunk’s IRI. With no embedding model this is BM25 full-text search.

3. Add embeddings

Point the embedding slot at any OpenAI-compatible endpoint. A local Ollama works:

ollama pull nomic-embed-text
fluree config set doc.embedding.url http://localhost:11434/v1
fluree config set doc.embedding.model nomic-embed-text
fluree doc ingest ./contracts -l contracts

The documents are re-ingested — the embedding model changed, so they are no longer “unchanged” — and each chunk now carries an embedding. fluree doc search now runs both methods and fuses them (--mode hybrid, the default once chunks carry embeddings); --mode vector and --mode text give you one or the other.

Or skip model configuration entirely by connecting a Fluree AI account.

4. Look at the graph

A chunk is a node. Its doc:sourceElement values are the paragraphs and table cells it was built from, and those carry offsets, page and box:

fluree query contracts -e '{
  "@context": {"doc": "https://ns.flur.ee/doc#", "nif": "http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#"},
  "where": [
    {"@id": "urn:fluree:doc:msa-2024.pdf/chunk/97", "doc:sourceElement": "?el"},
    {"@id": "?el", "doc:pageIndex": "?page", "doc:bbox": "?box", "nif:beginIndex": "?start"}
  ],
  "select": ["?el", "?page", "?box", "?start"]
}'

From there the whole graph is open: the section containing the element, the document node with the file’s hash and ingest time, or the same passage at an earlier commit. See Querying the graph.

5. Say what it is about

Point the ingest at the entities you already have and, if you want relations, at an ontology:

fluree doc ingest ./contracts -l contracts --entities counterparties.ttl --model ./contracts-ontology.ttl

Every mention of a counterparty is written against the IRI it has in counterparties.ttl, so a query across that graph and the contracts joins on the same node. The ontology needs a language model in the llm slot or a Fluree AI account; the mentions alone need nothing. See Entities and relations.