pub struct CypherEngine { /* private fields */ }Expand description
Cypher query engine with a cached catalog for efficient multi-query execution.
The engine registers each dataset once and reuses the catalog and DataFusion context across queries.
Lance datasets are read lazily from storage, pinned to the version they were
opened at: writes made later (by this or another process) are not visible until
refresh. Each dataset is pinned separately; versions across
tables are not a transactional multi-table snapshot. Arrow batches are held in
memory and never change; build a new engine to replace them.
Building the CSR (use_csr) is CPU-bound work inside an async function: in an
application with its own async runtime, construct and refresh the engine on a
blocking thread (for example tokio::task::spawn_blocking plus block_on).
Implementations§
Source§impl CypherEngine
impl CypherEngine
Sourcepub async fn new(
config: GraphConfig,
sources: HashMap<String, EngineSource>,
use_csr: bool,
) -> Result<Self>
pub async fn new( config: GraphConfig, sources: HashMap<String, EngineSource>, use_csr: bool, ) -> Result<Self>
Register sources (dataset name -> data) and build the snapshot.
Lance datasets are not read here, except for the CSR, node-index and
join-key statistics builds. With use_csr, relationship types with integer
endpoints get CSR adjacencies and node labels with unique integer ids get a
node index.
§Errors
GraphError::ConfigError if sources is empty or a configured id/endpoint
column is missing; GraphError::ExecutionError if a dataset cannot be
registered or scanned.
Sourcepub async fn with_target_partitions(
config: GraphConfig,
sources: HashMap<String, EngineSource>,
use_csr: bool,
target_partitions: Option<usize>,
) -> Result<Self>
pub async fn with_target_partitions( config: GraphConfig, sources: HashMap<String, EngineSource>, use_csr: bool, target_partitions: Option<usize>, ) -> Result<Self>
Like new, with a target for DataFusion query partitioning.
Some(n) sets DataFusion’s target_partitions for every query, kept across
refresh; None keeps DataFusion’s default (the number of
cores). It is not a thread or memory limit. In-memory Arrow inputs are still
sliced into one partition per core.
§Errors
As new, plus GraphError::ConfigError if target_partitions
is outside 1..=1024.
Sourcepub async fn execute(
&self,
query: &str,
params: HashMap<String, JsonValue>,
) -> Result<RecordBatch>
pub async fn execute( &self, query: &str, params: HashMap<String, JsonValue>, ) -> Result<RecordBatch>
Execute a Cypher query and return the whole result as one batch.
params gives values for $name parameters in the query. Use
execute_stream for large outputs.
Sourcepub async fn execute_stream(
&self,
query: &str,
params: HashMap<String, JsonValue>,
) -> Result<SendableRecordBatchStream>
pub async fn execute_stream( &self, query: &str, params: HashMap<String, JsonValue>, ) -> Result<SendableRecordBatchStream>
Execute a Cypher query and stream the result.
Batches are computed as the stream is polled. Scans, filters and projections
stream with bounded memory; joins, sorts and aggregations may still buffer.
The stream keeps what it reads alive, so a concurrent refresh() does not
affect it. Planning errors return here; execution errors arrive in the stream.
Dropping the stream cancels the remaining work.
Sourcepub async fn explain(
&self,
query: &str,
params: HashMap<String, JsonValue>,
) -> Result<String>
pub async fn explain( &self, query: &str, params: HashMap<String, JsonValue>, ) -> Result<String>
Return the query plan, including the physical plan with pushed-down scans.
Sourcepub async fn execute_with_vector_rerank(
&self,
query: &str,
vector_search: &VectorSearch,
) -> Result<RecordBatch>
pub async fn execute_with_vector_rerank( &self, query: &str, vector_search: &VectorSearch, ) -> Result<RecordBatch>
Execute a Cypher query, then rerank its rows by vector similarity.
Sourcepub async fn refresh(&self) -> Result<()>
pub async fn refresh(&self) -> Result<()>
Move every Lance dataset to its latest version.
Datasets whose version and commit time are unchanged keep their open handle. The replacement is validated in full before it is swapped in; on error nothing changes and the previous snapshot stays usable. Queries already running finish on the snapshot they started with. Arrow inputs are unchanged. Concurrent calls run one at a time.
Sourcepub fn csr_stats(&self) -> HashMap<String, CsrStats>
pub fn csr_stats(&self) -> HashMap<String, CsrStats>
CSR adjacency statistics per relationship type (experimental, use_csr).
An identical map after refresh() means the snapshot itself was unchanged.
Sourcepub fn node_index_stats(&self) -> HashMap<String, NodeIndexStats>
pub fn node_index_stats(&self) -> HashMap<String, NodeIndexStats>
Node id -> row index statistics per node label (experimental, use_csr).
A label is missing when its ids are not unique integers; its targets then use a join.
Sourcepub fn dataset_versions(&self) -> HashMap<String, u64>
pub fn dataset_versions(&self) -> HashMap<String, u64>
Pinned version of each Lance dataset, keyed by dataset name.
Sourcepub fn config(&self) -> &GraphConfig
pub fn config(&self) -> &GraphConfig
The graph configuration the engine was built with.
Auto Trait Implementations§
impl !Freeze for CypherEngine
impl !RefUnwindSafe for CypherEngine
impl Send for CypherEngine
impl Sync for CypherEngine
impl Unpin for CypherEngine
impl UnsafeUnpin for CypherEngine
impl UnwindSafe for CypherEngine
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> DropFlavorWrapper<T> for T
impl<T> DropFlavorWrapper<T> for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Requestimpl<T> MaybeSend for Twhere
T: Send,
impl<T> MaybeSend for Twhere
T: Send,
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.