use std::sync::Once;
use zvec_rust::*;
static INIT: Once = Once::new();
fn ensure_initialized() {
INIT.call_once(|| {
initialize(None).expect("failed to initialize zvec");
});
}
#[test]
fn test_fts_only_query_returns_keyword_matches() {
ensure_initialized();
let tmp_dir = tempfile::tempdir().unwrap();
let dir = tmp_dir.path().join("zvec_data");
let schema = CollectionSchema::builder("fts_no_vector_test")
.add_field(FieldSchema::new("id", DataType::String, false, 0).unwrap())
.add_indexed_field(
"content",
DataType::String,
IndexParams::fts(None, None, None).unwrap(),
)
.build()
.expect("failed to build schema");
let collection = Collection::create_and_open(dir.to_str().unwrap(), &schema, None)
.expect("failed to create collection");
let texts = [
"machine learning is fun",
"deep learning uses neural networks",
"vector databases store embeddings",
];
let mut docs = Vec::new();
for (i, text) in texts.iter().enumerate() {
let mut doc = Doc::new().unwrap();
doc.set_pk(&format!("pk_{}", i));
doc.add_string("id", &format!("pk_{}", i)).unwrap();
doc.add_string("content", text).unwrap();
docs.push(doc);
}
let doc_refs: Vec<&Doc> = docs.iter().collect();
let result = collection.insert(&doc_refs).unwrap();
assert_eq!(result.success_count, texts.len() as u64);
collection.flush().expect("flush before query");
let mut fts = Fts::new().unwrap();
fts.set_match_string("learning").unwrap();
let query = SearchQuery::fts("content", &fts, 10).expect("build vector-less FTS query");
let results = collection
.query(&query)
.expect("vector-less FTS query must run");
let mut got: Vec<String> = results
.iter()
.map(|d| d.get_string("content").unwrap().unwrap())
.collect();
got.sort();
assert_eq!(
got,
vec![
"deep learning uses neural networks".to_string(),
"machine learning is fun".to_string(),
],
"keyword query must return exactly the two matching rows"
);
}