Getting started with Apache Lucene
|
This section documents the current Apache Lucene 10.x line — Lucene 10 requires Java 21 — as published
at the Apache Lucene documentation and Javadoc, which is the reference these
pages are written and verified against. No specific patch version is pinned; examples target This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, as Lucene iterates quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
Apache Lucene is a search library, not a server: you add a JAR to a JVM application and call its classes directly. This page explains what that means in practice, lists the Maven and Gradle coordinates for the modules used throughout this section, and walks one document through indexing and back out of a query.
Lucene is an embedded, in-process library
Lucene runs inside your JVM. There is no daemon to start, no port to open, no wire protocol, and
nothing to deploy separately — an IndexWriter is an object you construct, and the index is a
directory of files on a disk you choose. The flip side is that everything a search server would do
for you is now your responsibility: concurrency control, when and how to persist, moving an index
between machines, replication, and sharding a corpus that outgrows one node. Lucene gives you the
inverted index, the query evaluation, and the scoring; the operational layer around it is yours to
build or to borrow.
That operational layer is exactly what Elasticsearch, OpenSearch, and Apache Solr are: all three embed this same Lucene library and wrap it in a cluster, a REST API, and a persistence/replication model. Lucene vs. Solr vs. Elasticsearch vs. OpenSearch compares them directly.
These pages target the Lucene 10.x line. Lucene 10 requires Java 21, and the default directory
implementation, MMapDirectory, memory-maps index files through the Java Platform’s foreign-memory
(Panama) API — see Directory implementations &
storage. The current requirements are on the
Apache Lucene site and its
system-requirements page.
// No client, no connection string: you open a directory and construct a writer.
// https://lucene.apache.org/core/10_0_0/core/org/apache/lucene/store/FSDirectory.html
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import java.nio.file.Path;
try (Directory dir = FSDirectory.open(Path.of("/var/data/my-index"));
IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(new StandardAnalyzer()))) {
// ... index documents ...
}
Adding Lucene to a build
org.apache.lucene:lucene-core is the only mandatory dependency. The rest of this section draws on a
set of companion modules, each a separate artifact under the same group and version; add only the
ones a page actually uses. The Javadoc for every module is linked from the
Lucene 10 API index.
| Module | Used for |
|---|---|
|
|
|
|
|
|
|
|
|
The |
|
Autocomplete and "did you mean" — |
|
|
|
First-pass/second-pass result grouping. |
|
JavaScript expression |
|
Extra |
|
Grid (prefix-tree) and serialized-DV spatial strategies on top of core’s |
|
Reverse search / stored-query matching — Monitor / reverse search. |
|
Read indexes written by the previous major version. |
|
|
<!-- Maven: lucene-core plus the two modules almost every app also needs. -->
<!-- https://lucene.apache.org/core/10_0_0/core/index.html -->
<dependencies>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>10.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analysis-common</artifactId>
<version>10.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>10.0.0</version>
</dependency>
</dependencies>
// Gradle (Groovy DSL): keep the version in one place and reuse it.
def luceneVersion = '10.0.0'
dependencies {
implementation "org.apache.lucene:lucene-core:${luceneVersion}"
implementation "org.apache.lucene:lucene-analysis-common:${luceneVersion}"
implementation "org.apache.lucene:lucene-queryparser:${luceneVersion}"
// add as needed, e.g.
// implementation "org.apache.lucene:lucene-facet:${luceneVersion}"
// implementation "org.apache.lucene:lucene-highlighter:${luceneVersion}"
testImplementation "org.apache.lucene:lucene-test-framework:${luceneVersion}"
}
The distribution also bundles lucene-demo, a runnable example whose IndexFiles and SearchFiles
classes index a directory tree and query it from the command line — a working reference for the code
below. See the lucene-demo module docs.
A first index-and-search round-trip
The following opens a Directory, writes two documents with an IndexWriter, opens a
DirectoryReader and an IndexSearcher, and runs two queries: a TermQuery built directly, and a
query produced by the string parser. TopDocs holds the ranked hit list; the stored fields of each
hit are read back through searcher.storedFields().
// https://lucene.apache.org/core/10_0_0/core/org/apache/lucene/index/IndexWriter.html
// https://lucene.apache.org/core/10_0_0/core/org/apache/lucene/search/IndexSearcher.html
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.*;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import java.nio.file.Path;
Directory dir = FSDirectory.open(Path.of("/var/data/books-index"));
StandardAnalyzer analyzer = new StandardAnalyzer();
// --- index ---
try (IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(analyzer))) {
Document a = new Document();
a.add(new StringField("isbn", "9780134685991", Field.Store.YES)); // exact term
a.add(new TextField("title", "Effective Java", Field.Store.YES)); // analyzed
writer.addDocument(a);
Document b = new Document();
b.add(new StringField("isbn", "9780596009205", Field.Store.YES));
b.add(new TextField("title", "Head First Java", Field.Store.YES));
writer.addDocument(b);
} // close() commits
// --- search ---
try (DirectoryReader reader = DirectoryReader.open(dir)) {
IndexSearcher searcher = new IndexSearcher(reader);
// 1. a Query built in code
Query exact = new TermQuery(new Term("isbn", "9780134685991"));
TopDocs byIsbn = searcher.search(exact, 10);
// 2. a Query parsed from a string ("java" is analyzed the same way the field was)
Query parsed = new QueryParser("title", analyzer).parse("java");
TopDocs byTitle = searcher.search(parsed, 10);
StoredFields stored = searcher.storedFields();
for (ScoreDoc hit : byTitle.scoreDocs) {
Document doc = stored.document(hit.doc);
System.out.printf("%.3f %s %s%n", hit.score, doc.get("isbn"), doc.get("title"));
}
}
Each of those objects is a chain: IndexWriterConfig carries the Analyzer, the Directory holds
the segments, the DirectoryReader gives the IndexSearcher a point-in-time view, and the Query
produces TopDocs. The index model & class
chains draws that out. The field choice above — StringField for the exact ISBN, TextField for
the analyzed title — is the subject of Documents,
fields & the capability matrix, and the two query forms open
Core queries.
Where to go next
-
lucene-core Javadoc — start at the
org.apache.luceneoverview and thecore/package summary. -
lucene-demo module — the
IndexFiles/SearchFilessample described above. -
lucene.apache.org/core — the project front page, release notes, and the migration guide between major versions.
-
System requirements — supported JVMs and platforms for the 10.x line.
Related pages
-
The index model & class chains — what the
Directory, writer, reader, and searcher above actually are. -
Documents, fields & the capability matrix — how to pick
TextFieldvs.StringFieldvs. the point and doc-values types. -
Core queries —
TermQuery,BooleanQuery.Builder,PhraseQuery.Builder, and range queries. -
Lucene vs. Solr vs. Elasticsearch vs. OpenSearch — what the servers add on top of this library.
-
Elasticsearch getting started and Solr getting started — the same round-trip against a server instead of a library.
-
Choosing the Right Database — where a search library or search server fits next to the other stores.