Embedded full-text search engine: inverted index, BM25 ranking, Chinese/English tokenization, crash-safe segments, runs on native/WASM/JS.
let index = @moonseek.Index::new([
{ name: "title", weight: 3.0 },
{ name: "body", weight: 1.0 },
])
index.add({
id: "doc1",
fields: [
("title", "全文搜索引擎"),
("body", "倒排索引是搜索引擎的核心,BM25 负责排序。"),
],
})
index.add({
id: "doc2",
fields: [("title", "MoonBit"), ("body", "A fast language for WebAssembly")],
})
let hits = index.search("搜索引擎") // [{ id: "doc1", score: … }]
let hits2 = index.search("title:moonbit") // field-scoped
let hits3 = index.search("\"memory safety\" OR wasm*") // phrase + prefix
// Persist (native)
index.save("index.msk")
let restored = @moonseek.Index::load("index.msk")
// Or portable bytes (works on every backend)
let image : Bytes = index.to_bytes()
let restored2 = @moonseek.Index::from_bytes(image)moon run cmd/main -- index ./docs --index index.msk # index .txt/.md files
moon run cmd/main -- search "搜索引擎" --index index.msk
moon run cmd/main -- search "title:rust" --limit 5
moon run cmd/main -- info --index index.mskmoon build --target wasm-gc
cp _build/wasm-gc/debug/build/web/web.wasm demo/web.wasm
cd demo && python -m http.server 8000
# open http://localhost:8000 (Chrome / Edge with WasmGC + js-string builtins)| Operation | Time |
|---|---|
| Index 1000 docs | ~89 ms |
| Term query (top-10) | ~1.0 ms |
| Phrase query (top-10) | ~2.9 ms |
| Snapshot save+load | ~30 ms |
token.mbt Analyzer: Latin words + CJK bigrams, positions
index.mbt Inverted index, field stats, BM25 scoring
query.mbt Lexer → recursive-descent parser → evaluator
codec.mbt Varint / UTF-8 / double / CRC-32 primitives
snapshot.mbt MSK1 format: versioned payload + checksum
store.mbt Native atomic file persistence (async/fs)
web/ Browser exports (#export_name, js-string builtins)
cmd/main/ CLI: index / search / info
demo/ Single-page browser demomoon test # 43 tests (native), 39 (wasm-gc / js)
moon test --target wasm-gc
moon test --target js
moon bench --release # benchmarkspub struct Index {
schema : Array[FieldSchema]
analyzer : Analyzer
bm25 : Bm25Params
postings : HashMap[String, HashMap[String, Array[Posting]]]
doc_ids : Array[String]
doc_nums : HashMap[String, Int]
stats : HashMap[String, FieldStats]
deleted : HashMap[Int, Unit]
}async fn Index::load_or_create(path : String, schema : Array[FieldSchema]) -> Index raise StoreErrortype Parserpub struct Reader {
data : Bytes
pos : Int
}fn parse_query(input : String, analyzer? : Analyzer, fields? : Array[String]) -> Query raise QueryErrorInstall
Download zipEmbedded full-text search engine: inverted index, BM25 ranking, Chinese/English tokenization, crash-safe segments, runs on native/WASM/JS.