use serde_json::{Value, json};
use crate::{Engine, SpaceType};
pub fn create_index_body(
dimensions: usize,
space_type: SpaceType,
engine: Engine,
m: Option<usize>,
ef_construction: Option<usize>,
) -> Value {
let mut params = serde_json::Map::new();
if let Some(m) = m {
params.insert("m".into(), json!(m));
}
if let Some(ef) = ef_construction {
params.insert("ef_construction".into(), json!(ef));
}
json!({
"settings": {
"index": {
"knn": true
}
},
"mappings": {
"properties": {
"embedding": {
"type": "knn_vector",
"dimension": dimensions,
"method": {
"name": "hnsw",
"space_type": space_type.as_str(),
"engine": engine.as_str(),
"parameters": params
}
},
"content": {
"type": "text"
},
"metadata": {
"type": "object",
"enabled": true
}
}
}
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_index_body_defaults() {
let body = create_index_body(
1536,
SpaceType::CosineSimilarity,
Engine::Lucene,
None,
None,
);
assert!(body["settings"]["index"]["knn"].as_bool().unwrap());
assert_eq!(
body["mappings"]["properties"]["embedding"]["dimension"],
1536
);
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["space_type"],
"cosinesimil"
);
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["engine"],
"lucene"
);
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["name"],
"hnsw"
);
assert!(
body["mappings"]["properties"]["embedding"]["method"]["parameters"]
.as_object()
.unwrap()
.is_empty()
);
}
#[test]
fn test_create_index_body_custom_params() {
let body = create_index_body(768, SpaceType::L2, Engine::Faiss, Some(32), Some(256));
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["parameters"]["m"],
32
);
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["parameters"]["ef_construction"],
256
);
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["space_type"],
"l2"
);
assert_eq!(
body["mappings"]["properties"]["embedding"]["method"]["engine"],
"faiss"
);
}
}