///|
/// Run the same query against a flat index and return results in input order.
pub fn FlatIndex::search_batch(
self : FlatIndex,
queries : Array[Array[Double]],
top_k : Int,
metric : DistanceMetric,
filters : Array[(String, String)],
) -> Array[Array[SearchResult]] raise VectorError {
let all = []
for query in queries {
all.push(self.search(query, top_k, metric, filters))
}
all
}
///|
/// Search a batch using IVF-Flat with the same probe budget for each query.
pub fn IvfIndex::search_batch(
self : IvfIndex,
queries : Array[Array[Double]],
top_k : Int,
nprobe : Int,
filters : Array[(String, String)],
) -> Array[Array[SearchResult]] raise VectorError {
let all = []
for query in queries {
all.push(self.search(query, top_k, nprobe, filters))
}
all
}
///|
/// Search a batch with the approximate LSH index.
pub fn LshIndex::search_batch(
self : LshIndex,
queries : Array[Array[Double]],
top_k : Int,
filters : Array[(String, String)],
) -> Array[Array[SearchResult]] raise VectorError {
let all = []
for query in queries {
all.push(self.search(query, top_k, filters))
}
all
}
///|
/// Find the first result with the requested document id.
pub fn find_result(results : Array[SearchResult], id : String) -> SearchResult? {
for result in results {
if result.id == id {
return Some(result)
}
}
None
}
///|
/// Calculate recall@k between an approximate result list and an exact list.
pub fn recall_at_k(
approximate : Array[SearchResult],
exact : Array[SearchResult],
k : Int,
) -> Double {
if k <= 0 || exact.length() == 0 {
return 0.0
}
let limit = if k < exact.length() { k } else { exact.length() }
let mut hits = 0
for i = 0; i < limit; i = i + 1 {
if find_result(approximate, exact[i].id) is Some(_) {
hits = hits + 1
}
}
hits.to_double() / limit.to_double()
}
///|
/// Calculate the mean recall of corresponding query batches.
pub fn mean_recall(
approximate : Array[Array[SearchResult]],
exact : Array[Array[SearchResult]],
k : Int,
) -> Double {
if approximate.length() == 0 || exact.length() == 0 {
return 0.0
}
let count = if approximate.length() < exact.length() {
approximate.length()
} else {
exact.length()
}
let mut total = 0.0
for i = 0; i < count; i = i + 1 {
total = total + recall_at_k(approximate[i], exact[i], k)
}
total / count.to_double()
}