Skip to content

About

This local search engine is a high-performance, local file indexing and search application built in Java. Designed for rapid information retrieval, it features incremental file traversal, symlink loop detection, and lightning-fast full-text search powered by SQLite FTS5

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

111 Commits

Folders and files

Repository files navigation

Search Engine

A local file search engine built for the Software Design 2026 course at TU Cluj-Napoca. It indexes a directory tree on your machine and searches inside your files, through a JavaFX GUI and a CLI, backed by SQLite FTS5.

Current version: 3.0.0 (Iteration 3). See CHANGELOG.md for the full history.


Features

Indexing

  • Producer-consumer pipeline: parallel reader threads for extraction, one dedicated writer thread, bounded queue for backpressure, batched commits
  • Incremental indexing, only files whose lastModified changed are re-read
  • Live re-indexing via FileWatcher on Java's WatchService, applies creates, edits and deletes after the initial index
  • Symlink loop detection through canonical path resolution and a visited set
  • Stale entry cleanup for deleted files
  • Apache Tika parsing for PDF, DOCX and HTML, plus binary file safety
  • Dominant colour extraction for images via pixel sampling
  • Configurable ignore rules, editable in the UI

Search

  • Full-text search on SQLite FTS5 with BM25 ranking
  • Filename matches weighted 10x over content matches
  • PathScorer, a 0 to 10 query-independent relevance score computed at index time
  • Five ranking strategies: relevance, path score, date, size, alphabetical
  • Query preprocessing decorator pipeline: sanitization, synonym expansion, automatic wildcards
  • Boolean operators, wildcards and phrase search through native FTS5 syntax
  • Qualifiers: ext:, path:, name:, content:, color:
  • Search history with autocomplete suggestions and behaviour-based result boosting

Interface

  • JavaFX GUI (MVVM) with live search, 350ms debounce, term highlighting, file preview and pagination
  • Context-aware widget strip: gallery widget for image-heavy results, log analyzer for log-heavy results
  • Search analytics dashboard with session and database statistics
  • Interactive CLI with TEXT and JSON report export

Tech Stack

Layer Technology
Language Java 21
Build Maven
Database SQLite + FTS5 (xerial/sqlite-jdbc 3.45.1.0)
Parsing Apache Tika 2.9.1
GUI JavaFX 17.0.2 + AtlantaFX NordDark
Testing JUnit 5.10.2, Mockito 5.11.0
Formatting Spotless + Google Java Format

Project Structure

src/main/java/app/
├── Main.java                       — CLI composition root
├── cli/CLI.java                    — interactive CLI
├── config/IndexConfig.java         — runtime configuration and ignore defaults
├── db/
│   ├── Database.java               — connection, pragmas, schema, migrations
│   └── FileRepository.java         — all SQL queries
├── gui/
│   ├── MainApp.java                — JavaFX entry point
│   ├── SearchController.java       — FXML controller
│   ├── SearchViewModel.java        — search state
│   ├── IndexViewModel.java         — indexing state and progress
│   ├── ResultCellFactory.java      — custom result cells
│   ├── TextHighlighter.java        — match highlighting in previews
│   └── widget/                     — context-aware widget strip
│       ├── ContextWidget.java
│       ├── WidgetFactory.java
│       ├── GalleryWidget.java
│       └── LogAnalyzerWidget.java
├── indexer/
│   ├── FileIndexer.java            — traversal, producer-consumer pipeline
│   ├── FileWatcher.java            — live filesystem watching
│   ├── FileFilter.java             — directory and extension filtering
│   ├── PathScorer.java             — query-independent relevance score
│   └── IndexerFactory.java
├── model/                          — FileRecord, SearchResult, IndexReport, TraversalStats
├── processor/
│   ├── ContentExtractor.java       — strategy dispatch by MIME type
│   └── strategy/                   — TextExtractionStrategy, ImageExtractionStrategy
├── search/
│   ├── SearchEngine.java           — search subject, notifies observers
│   ├── SearchRequestParser.java    — qualifier parsing
│   ├── RankingStrategy.java        — ranking strategies
│   ├── SearchHistoryService.java   — history observer, suggestions, boosting
│   ├── SearchObserver.java / SearchEvent.java
│   └── preprocessor/               — Sanitization, Synonym and Logic decorators
└── util/FileTypes.java             — text and image extension registries

Running the Project

GUI

mvn javafx:run
  1. Enter or browse to a directory
  2. Click Index, progress is shown live in the status bar
  3. Type in the search bar, results appear as you type
  4. Filter by extension, path or dominant colour, or change the sort strategy
  5. Click a result to preview it, with matched terms highlighted

CLI

mvn compile exec:java -Dexec.mainClass="app.Main" -Dexec.args="D:\YourDirectory"

Arguments: <directory> [database] [TEXT|JSON]. Defaults are the user home directory, vision_index.db and TEXT.


Search Syntax

Syntax Example Description
keyword main Full-text search, wildcard implied
phrase "public static void" Exact phrase
boolean index AND NOT test AND, OR, NOT
wildcard index* Prefix match
extension main ext:java ext:kt Filter by extension, OR semantics
path config path:src Filter by path substring
name name:Indexer Match filename only
content content:bm25 Match file content only
colour logo ext:png color:blue Filter images by dominant colour

Queries pass through a decorator pipeline before reaching FTS5. Unqualified terms are sanitized, expanded through synonyms.properties, and given a trailing wildcard, so index also matches indexer and indexing.


Ranking

Two independent signals decide result order.

BM25, from FTS5, scores query relevance. The name column is weighted 10x over content, so searching FileIndexer surfaces the file itself above the files that merely mention it.

PathScorer computes a 0 to 10 score per file at index time, independent of any query, stored in the files table and indexed with a B-tree. Source extensions weigh more than config and markup, paths under /src/main/ are boosted, vendor, generated and node_modules paths are penalised, and deeply nested paths decay slightly. It is a heuristic, and its purpose is to push your own code above everything vendored into your tree.

Results returned for queries you actually run gain a small persistent boost, capped so that history can nudge ranking without dominating it.


Database Schema

CREATE TABLE files (
    path          TEXT    PRIMARY KEY,
    name          TEXT    NOT NULL,
    extension     TEXT,
    sizeBytes     INTEGER NOT NULL,
    lastModified  INTEGER NOT NULL,
    preview       TEXT,
    pathScore     REAL    NOT NULL DEFAULT 0.0,
    dominantColor TEXT
);

CREATE VIRTUAL TABLE files_fts USING fts5(
    path UNINDEXED,
    name,
    content
);

B-tree indexes on extension, lastModified DESC, sizeBytes DESC, pathScore DESC and dominantColor. Schema changes are applied through guarded ALTER TABLE migrations, so existing databases upgrade in place.

Pragmas: journal_mode = WAL for concurrent CLI and GUI access, cache_size = -32000 for a 32MB page cache, synchronous = NORMAL.


Ignored by Default

Directories: .git, .idea, .hidden, node_modules, target, build, dist, cache, env, venv, AppData, flutter, scoop, __pycache__

Extensions: class, obj, o, pyc, pyo, zip, tar, gz, rar, 7z, tmp, bak, lnk, db, sqlite, lock, iml, suo, user, map, DS_Store

Everything else is indexed by metadata. Text files, documents parsed by Tika and images additionally get their content or dominant colour indexed.


Tests

mvn test

Unit tests cover the query decorator pipeline, the request parser, the path scorer, the search history service and content extraction. RankingIntegrationTest runs the full ranking path against an in-memory SQLite database.


Architecture

See ARCHITECTURE.md for the full C4 model covering system context, containers, components and runtime sequence diagrams.

Design patterns in use: Strategy for ranking and extraction, Decorator for the query pipeline, Observer for search history, Factory for indexers and widgets, MVVM in the GUI.

About

This local search engine is a high-performance, local file indexing and search application built in Java. Designed for rapid information retrieval, it features incremental file traversal, symlink loop detection, and lightning-fast full-text search powered by SQLite FTS5

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages