Skip to main content
This guide walks you through a minimal but complete Lucene workflow: declare a dependency, create an in-memory index, add documents, and query them.
These examples require Java 25 and Lucene 11.0.0. Lucene 11 targets Java 25 as its minimum platform.
1

Add the dependency

Lucene is published to Maven Central. Add lucene-core to your build file. For full-text search with a query parser, also add lucene-queryparser.
<dependencies>
  <dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-core</artifactId>
    <version>11.0.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-analysis-common</artifactId>
    <version>11.0.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>11.0.0</version>
  </dependency>
</dependencies>
lucene-core contains IndexWriter, IndexSearcher, Directory, and the document/field types. The lucene-analysis-common module provides StandardAnalyzer. The lucene-queryparser module provides QueryParser used in step 4.
2

Create an index

A Directory is Lucene’s abstraction for index storage. Use ByteBuffersDirectory for an in-memory index during development or testing. Use FSDirectory.open(path) to persist an index to disk, as shown in the demo’s IndexFiles.java.
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.ByteBuffersDirectory;
import org.apache.lucene.store.Directory;

// In-memory directory — no files written to disk
Directory directory = new ByteBuffersDirectory();

// StandardAnalyzer tokenizes, lowercases, and removes common stop words
StandardAnalyzer analyzer = new StandardAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);

IndexWriter writer = new IndexWriter(directory, config);
To write to disk instead, replace the directory line:
import org.apache.lucene.store.FSDirectory;
import java.nio.file.Paths;

Directory directory = FSDirectory.open(Paths.get("/path/to/index"));
3

Add documents

A Document is a collection of Fields. Choose the right field type for each piece of data:
  • TextField — tokenized full-text content (body, title, description). The analyzer runs on the value.
  • StringField — exact-match string stored and indexed as a single token (IDs, paths, categories). Not analyzed.
  • LongField — numeric value suitable for range queries and sorting.
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;

// First document
Document doc1 = new Document();
doc1.add(new StringField("id", "1", Field.Store.YES));
doc1.add(new TextField("title", "Apache Lucene Getting Started", Field.Store.YES));
doc1.add(new TextField("body",
    "Lucene is a high-performance search library written in Java.",
    Field.Store.YES));
writer.addDocument(doc1);

// Second document
Document doc2 = new Document();
doc2.add(new StringField("id", "2", Field.Store.YES));
doc2.add(new TextField("title", "Indexing and Searching with Lucene", Field.Store.YES));
doc2.add(new TextField("body",
    "IndexWriter writes documents into segments. IndexSearcher queries them.",
    Field.Store.YES));
writer.addDocument(doc2);

// Commit makes the documents visible to new readers
writer.commit();
writer.close();
Field.Store.YES stores the raw value so you can retrieve it from search results. Field.Store.NO indexes the field for searching but does not store it — useful when you only need to know which document matched, not the original value.
4

Search the index

Open a DirectoryReader to get a read-only view of the index, then wrap it in an IndexSearcher. Use QueryParser to parse a query string against a default field, or construct Query objects directly.
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.StoredFields;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

// Open the index for reading
DirectoryReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);

// Parse a query against the "body" field
QueryParser parser = new QueryParser("body", new StandardAnalyzer());
Query query = parser.parse("Lucene search library");

// Search and retrieve the top 10 results
TopDocs results = searcher.search(query, 10);
System.out.println("Found " + results.totalHits.value() + " document(s).");

// Retrieve stored field values for each hit
StoredFields storedFields = searcher.storedFields();
for (ScoreDoc hit : results.scoreDocs) {
    Document doc = storedFields.document(hit.doc);
    System.out.printf("  score=%.4f  id=%s  title=%s%n",
        hit.score,
        doc.get("id"),
        doc.get("title"));
}

reader.close();
Running this prints something like:
Found 2 document(s).
  score=0.4855  id=1  title=Apache Lucene Getting Started
  score=0.3128  id=2  title=Indexing and Searching with Lucene

Complete minimal example

The following is a single self-contained class combining all four steps above:
LuceneQuickstart.java
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.StoredFields;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.ByteBuffersDirectory;
import org.apache.lucene.store.Directory;

public class LuceneQuickstart {

    public static void main(String[] args) throws Exception {
        // 1. Create an in-memory index
        Directory directory = new ByteBuffersDirectory();
        StandardAnalyzer analyzer = new StandardAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);

        // 2. Write documents
        try (IndexWriter writer = new IndexWriter(directory, config)) {
            Document doc1 = new Document();
            doc1.add(new StringField("id", "1", Field.Store.YES));
            doc1.add(new TextField("title", "Apache Lucene Getting Started", Field.Store.YES));
            doc1.add(new TextField("body",
                "Lucene is a high-performance search library written in Java.",
                Field.Store.YES));
            writer.addDocument(doc1);

            Document doc2 = new Document();
            doc2.add(new StringField("id", "2", Field.Store.YES));
            doc2.add(new TextField("title", "Indexing and Searching with Lucene", Field.Store.YES));
            doc2.add(new TextField("body",
                "IndexWriter writes documents into segments. IndexSearcher queries them.",
                Field.Store.YES));
            writer.addDocument(doc2);
        } // writer.close() commits and flushes

        // 3. Search
        try (DirectoryReader reader = DirectoryReader.open(directory)) {
            IndexSearcher searcher = new IndexSearcher(reader);
            QueryParser parser = new QueryParser("body", new StandardAnalyzer());
            Query query = parser.parse("Lucene search library");

            TopDocs results = searcher.search(query, 10);
            System.out.println("Found " + results.totalHits.value() + " document(s).");

            StoredFields storedFields = searcher.storedFields();
            for (ScoreDoc hit : results.scoreDocs) {
                Document doc = storedFields.document(hit.doc);
                System.out.printf("  score=%.4f  id=%s  title=%s%n",
                    hit.score, doc.get("id"), doc.get("title"));
            }
        }
    }
}

Next steps

Core concepts

Learn about indexes, segments, analyzers, and query types before building a production system.

Demo source code

Study the full IndexFiles and SearchFiles demos in the Lucene repository.

Build docs developers (and LLMs) love