blob: c265aad3cebe861817bbb4f0c409ea16bf7b82a9 [file] [view]
# Apache Paimon Full Text Index
Standalone Tantivy-based full-text index library for Apache Paimon-style data
lake storage. The project follows the same shape as `paimon-vector-index`:
- `core`: Rust implementation and v1 storage format.
- `ffi`: C ABI over the Rust core.
- `jni`: Java JNI bridge over the Rust core.
- `java`: public Java API.
- `python`: Python ctypes API over the C ABI.
The index file is self-describing. Readers only need positional `read_at` I/O
and do not depend on Paimon manifest metadata.
## Current Status
Implemented:
- Rust writer, reader, v1 envelope, and search.
- C FFI writer/reader/search JSON.
- Java API and JNI bridge.
- Python ctypes package.
- Cross-boundary round-trip tests for Rust core, FFI, Java/JNI, and Python.
Supported tokenizers in this first implementation:
- `default`
- `simple`
- `whitespace`
- `raw`
- `ngram`
Reserved for follow-up:
- `jieba`
- stemming
- built-in and custom stop-word filters
- true seek-on-demand Tantivy directory instead of loading segment files into
memory at reader open
## Build
```bash
cargo test -p paimon-ftindex-core
cargo test -p paimon-ftindex-ffi
cargo build -p paimon-ftindex-ffi
cargo build -p paimon-ftindex-jni
mvn -q -f java/pom.xml test
PYTHONPATH=python python3 -m pytest -q python/tests
```
## Rust Example
```rust
use paimon_ftindex_core::io::{PosWriter, SliceReader};
use paimon_ftindex_core::{
FullTextIndexConfig, FullTextIndexReader, FullTextIndexWriter, FullTextQuery,
};
let mut writer = FullTextIndexWriter::new(FullTextIndexConfig::new())?;
writer.add_document(1, "Apache Paimon full text search")?;
let mut bytes = Vec::new();
writer.write(&mut PosWriter::new(&mut bytes))?;
let mut reader = FullTextIndexReader::open(SliceReader::new(bytes))?;
let result = reader.search(FullTextQuery::match_query("paimon", "text"), 10)?;
```
## Python Example
```python
from io import BytesIO
from paimon_ftindex import FullTextIndexReader, FullTextIndexWriter, MatchQuery
out = BytesIO()
with FullTextIndexWriter() as writer:
writer.add_document(1, "Apache Paimon full text search")
writer.write(out)
class Input:
def __init__(self, data):
self.data = data
def pread(self, pos, length):
return self.data[pos:pos + length]
with FullTextIndexReader(Input(out.getvalue())) as reader:
ids, scores = reader.search(MatchQuery("paimon"), limit=10)
```