use std::sync::Arc;
use datafusion::arrow::datatypes::*;
use qdrant_client::qdrant::{CollectionConfig, Datatype, VectorParams, vectors_config};
use crate::error::{Error, Result};
pub fn is_multi_vector_field(field: &Field) -> bool {
matches!(
field.data_type(),
DataType::List(inner) if matches!(inner.data_type(), DataType::List(_))
)
}
pub fn datatype_to_arrow(_dt: Datatype) -> DataType {
DataType::Float32
}
pub fn create_vector_field(name: &str, dt: Datatype, nullable: bool) -> FieldRef {
Field::new(name, datatype_to_arrow(dt), nullable).into()
}
pub fn create_vector_param_field(name: &str, vector_params: &VectorParams) -> Field {
if vector_params.multivector_config.is_some() {
Field::new(
name,
DataType::List(Arc::new(Field::new(
"item",
DataType::List(create_vector_field("item", vector_params.datatype(), true)),
true,
))),
true, )
} else {
Field::new(
name,
DataType::List(create_vector_field("item", vector_params.datatype(), true)),
true, )
}
}
pub fn collection_to_arrow_schema(collection: &str, config: &CollectionConfig) -> Result<Schema> {
let mut fields = vec![
Field::new("id", DataType::Utf8, false),
Field::new("payload", DataType::Utf8, true),
];
let params =
config.params.as_ref().ok_or(Error::MissingCollectionInfoParams(collection.into()))?;
if let Some(config) = params.vectors_config.as_ref().and_then(|c| c.config.as_ref()) {
match config {
vectors_config::Config::Params(vector_params) => {
fields.push(create_vector_param_field("vector", vector_params));
}
vectors_config::Config::ParamsMap(params_map) => {
fields.extend(
params_map
.map
.iter()
.map(|(name, params)| create_vector_param_field(name, params)),
);
}
}
}
if let Some(sparse_config) = ¶ms.sparse_vectors_config {
for name in sparse_config.map.keys() {
fields.push(Field::new(
format!("{name}_indices"),
DataType::List(Field::new("item", DataType::UInt32, true).into()),
true, ));
fields.push(Field::new(
format!("{name}_values"),
DataType::List(create_vector_field("item", Datatype::Float32, true)),
true, ));
}
}
Ok(Schema::new(fields))
}