use crate::segment::data_types::order_by::OrderValue;
use crate::segment::data_types::segment_record::SegmentRecord;
use crate::segment::data_types::vectors::{DEFAULT_VECTOR_NAME, VectorRef, VectorStructInternal};
use crate::segment::types::{Payload, PointIdType, ShardKey, VectorName};
use crate::shard::operations::point_ops::{PointStructPersisted, VectorStructPersisted};
#[derive(Clone, Debug, PartialEq)]
pub struct RecordInternal {
pub id: PointIdType,
pub payload: Option<Payload>,
pub vector: Option<VectorStructInternal>,
pub shard_key: Option<ShardKey>,
pub order_value: Option<OrderValue>,
}
impl RecordInternal {
pub fn new_empty(id: PointIdType) -> Self {
Self {
id,
payload: None,
vector: None,
shard_key: None,
order_value: None,
}
}
pub fn get_vector_by_name(&self, name: &VectorName) -> Option<VectorRef<'_>> {
match &self.vector {
Some(VectorStructInternal::Single(vector)) => {
(name == DEFAULT_VECTOR_NAME).then_some(VectorRef::from(vector))
}
Some(VectorStructInternal::MultiDense(vectors)) => {
(name == DEFAULT_VECTOR_NAME).then_some(VectorRef::from(vectors))
}
Some(VectorStructInternal::Named(vectors)) => vectors.get(name).map(VectorRef::from),
None => None,
}
}
}
impl From<SegmentRecord> for RecordInternal {
fn from(record: SegmentRecord) -> Self {
let SegmentRecord {
id,
payload,
vectors,
} = record;
Self {
id,
payload,
vector: vectors.map(VectorStructInternal::from),
shard_key: None,
order_value: None,
}
}
}
impl TryFrom<RecordInternal> for PointStructPersisted {
type Error = String;
fn try_from(record: RecordInternal) -> Result<Self, Self::Error> {
let RecordInternal {
id,
payload,
vector,
shard_key: _,
order_value: _,
} = record;
if vector.is_none() {
return Err("Vector is empty".to_string());
}
Ok(Self {
id,
payload,
vector: VectorStructPersisted::from(vector.unwrap()),
})
}
}
#[cfg(feature = "api")]
impl From<RecordInternal> for api::grpc::qdrant::RetrievedPoint {
fn from(record: RecordInternal) -> Self {
use api::conversions::json::payload_to_proto;
use api::grpc::conversions::convert_shard_key_to_grpc;
let RecordInternal {
id,
payload,
vector,
shard_key,
order_value,
} = record;
Self {
id: Some(id.into()),
payload: payload.map(payload_to_proto).unwrap_or_default(),
vectors: vector.map(api::grpc::qdrant::VectorsOutput::from),
shard_key: shard_key.map(convert_shard_key_to_grpc),
order_value: order_value.map(From::from),
}
}
}
#[cfg(feature = "api")]
impl From<RecordInternal> for api::rest::Record {
fn from(value: RecordInternal) -> Self {
let RecordInternal {
id,
payload,
vector,
shard_key,
order_value,
} = value;
Self {
id,
payload,
vector: vector.map(api::rest::VectorStructOutput::from),
shard_key,
order_value,
}
}
}