Expand description
Neo4j driver compatible with neo4j 4.x versions
- An implementation of the bolt protocol to interact with Neo4j server
- async/await apis using tokio
- Supports bolt 4.2 specification
- tested with Neo4j versions: 4.0, 4.1, 4.2
§Examples
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let id = uuid::Uuid::new_v4().to_string(); let graph = Graph::new(uri, user, pass).await.unwrap(); { let id = uuid::Uuid::new_v4().to_string(); graph .run(query("CREATE (p:Person {id: $id})").param("id", id.clone())) .await .unwrap(); let mut handles = Vec::new(); let count = std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0)); for _ in 1..=42 { let graph = graph.clone(); let id = id.clone(); let count = count.clone(); let handle = tokio::spawn(async move { let mut result = graph .execute(query("MATCH (p:Person {id: $id}) RETURN p").param("id", id)) .await .unwrap(); while let Ok(Some(_row)) = result.next().await { count.fetch_add(1, std::sync::atomic::Ordering::Relaxed); } }); handles.push(handle); } futures::future::join_all(handles).await; assert_eq!(count.load(std::sync::atomic::Ordering::Relaxed), 42); } }§Configurations
Use the config builder to override the default configurations like
fetch_size- number of rows to fetch in batches (default is 200)max_connections- maximum size of the connection pool (default is 16)db- the database to connect to (default isneo4j)
use neo4rs::*; #[tokio::main] async fn main() { let config = ConfigBuilder::default() .uri("127.0.0.1:7687") .user("neo4j") .password("neo") .db("neo4j") .fetch_size(500) .max_connections(10) .build() .unwrap(); let graph = Graph::connect(config).await.unwrap(); { let mut result = graph.execute(query("RETURN 1")).await.unwrap(); let row = result.next().await.unwrap().unwrap(); let value: i64 = row.get("1").unwrap(); assert_eq!(1, value); assert!(result.next().await.unwrap().is_none()); } }§Nodes
A simple example to create a node and consume the created node from the row stream.
Graph::runjust returnserrors::Result<()>, usually used for write only queries.Graph::executereturnserrors::Result<RowStream>
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { assert!(graph.run(query("RETURN 1")).await.is_ok()); let mut result = graph .execute( query("CREATE (friend:Person {name: $name}) RETURN friend").param("name", "Mr Mark"), ) .await .unwrap(); #[derive(serde::Deserialize)] struct Person { labels: Labels, keys: Keys<Vec<String>>, name: String, } while let Ok(Some(row)) = result.next().await { // use serde to extract the relationship data let friend: Person = row.get("friend").unwrap(); assert_eq!(friend.name, "Mr Mark"); assert_eq!(friend.labels.0, vec!["Person"]); assert_eq!(friend.keys.0, vec!["name"]); // or use the neo4rs::Relation type let node: Node = row.get("friend").unwrap(); assert_eq!(node.get::<String>("name").unwrap(), "Mr Mark"); assert_eq!(node.labels(), vec!["Person"]); assert_eq!(node.keys(), vec!["name"]); assert!(node.id() >= 0); } } }§Transactions
Start a new transaction using Graph::start_txn, which will return a handle Txn that can be used to Txn::commit or Txn::rollback the transaction.
Note that the handle takes a connection from the connection pool, which will be released once the Txn is dropped
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let mut txn = graph.start_txn().await.unwrap(); let id = uuid::Uuid::new_v4().to_string(); let result = txn .run_queries([ query("CREATE (p:Person {id: $id})").param("id", id.clone()), query("CREATE (p:Person {id: $id})").param("id", id.clone()), ]) .await; assert!(result.is_ok()); txn.commit().await.unwrap(); let mut result = graph .execute(query("MATCH (p:Person) WHERE p.id = $id RETURN p.id").param("id", id.clone())) .await .unwrap(); assert!(result.next().await.unwrap().is_some()); assert!(result.next().await.unwrap().is_some()); assert!(result.next().await.unwrap().is_none()); } } §Streams within a transaction
Each RowStream returned by various execute functions within the same transaction are well isolated, so you can consume the stream anytime within the transaction using RowStream::next
use neo4rs::*; #[tokio::main] async fn main() { let config = ConfigBuilder::default() .uri("127.0.0.1:7687") .user("neo4j") .password("neo") .fetch_size(1) .build() .unwrap(); let graph = Graph::connect(config).await.unwrap(); { let name = uuid::Uuid::new_v4().to_string(); let mut txn = graph.start_txn().await.unwrap(); #[derive(serde::Deserialize)] struct Person { name: String, } txn.run_queries([ query("CREATE (p { name: $name })").param("name", name.clone()), query("CREATE (p { name: $name })").param("name", name.clone()), ]) .await .unwrap(); //start stream_one let mut stream_one = txn .execute(query("MATCH (p {name: $name}) RETURN p").param("name", name.clone())) .await .unwrap(); let row = stream_one.next(txn.handle()).await.unwrap().unwrap(); assert_eq!(row.to::<Person>().unwrap().name, name); //start stream_two let mut stream_two = txn.execute(query("RETURN 1")).await.unwrap(); let row = stream_two.next(txn.handle()).await.unwrap().unwrap(); assert_eq!(row.to::<i64>().unwrap(), 1); //stream_one is still active here let row = stream_one.next(txn.handle()).await.unwrap().unwrap(); assert_eq!(row.to::<Person>().unwrap().name, name); //stream_one completes assert!(stream_one.next(txn.handle()).await.unwrap().is_none()); //stream_two completes assert!(stream_two.next(txn.handle()).await.unwrap().is_none()); txn.commit().await.unwrap(); } } §Streams are evaluated lazily
The RowStream returned by various execute functions need to be consumed with RowStream::next in order to actually execute the query. The various run functions on the other hand are always executed eagerly.
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let before = graph .execute(query("MATCH (n:MyNode) RETURN COUNT(n) AS n")) .await .unwrap() .next() .await .unwrap() .unwrap() .get::<i64>("n") .unwrap(); // use `run` for fire-and-forget queries, that are being executed on the server graph .run(query("CREATE (n:MyNode {p: 'prop'})")) .await .unwrap(); // using `execute` without consuming the result will do nothing // This will trigger a `unused_must_use` warning graph .execute(query("CREATE (n:MyNode {p: 'prop'})")) .await .unwrap(); // consuming the result stream of`execute` will run the query on the server graph .execute(query("CREATE (n:MyNode {p: 'prop'})")) .await .unwrap() .next() .await .unwrap(); let after = graph .execute(query("MATCH (n:MyNode) RETURN COUNT(n) AS n")) .await .unwrap() .next() .await .unwrap() .unwrap() .get::<i64>("n") .unwrap(); assert_eq!(after, before + 2); } } §Rollback a transaction
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let mut txn = graph.start_txn().await.unwrap(); let id = uuid::Uuid::new_v4().to_string(); // create a node txn.run(query("CREATE (p:Person {id: $id})").param("id", id.clone())) .await .unwrap(); // rollback the changes txn.rollback().await.unwrap(); // changes not updated in the database let mut result = graph .execute(query("MATCH (p:Person) WHERE p.id = $id RETURN p.id").param("id", id.clone())) .await .unwrap(); assert!(result.next().await.unwrap().is_none()); } } §Txn vs Graph
Everytime you execute a query using Graph::run or Graph::execute, a new connection is taken from the pool and released immediately.
However, when you execute a query on a transaction using Txn::run or Txn::execute the same connection will be reused, the underlying connection will be released to the pool in a clean state only after you commit/rollback the transaction and the Txn handle is dropped.
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let mut txn = graph.start_txn().await.unwrap(); let id = uuid::Uuid::new_v4().to_string(); txn.run(query("CREATE (p:Person {id: $id})").param("id", id.clone())) .await .unwrap(); txn.run(query("CREATE (p:Person {id: $id})").param("id", id.clone())) .await .unwrap(); // graph.execute(..) will not see the changes done above as the txn is not committed yet let mut result = graph .execute(query("MATCH (p:Person) WHERE p.id = $id RETURN p.id").param("id", id.clone())) .await .unwrap(); assert!(result.next().await.unwrap().is_none()); txn.commit().await.unwrap(); //changes are now seen as the transaction is committed. let mut result = graph .execute(query("MATCH (p:Person) WHERE p.id = $id RETURN p.id").param("id", id.clone())) .await .unwrap(); assert!(result.next().await.unwrap().is_some()); assert!(result.next().await.unwrap().is_some()); assert!(result.next().await.unwrap().is_none()); } } §Relationships
Bounded Relationship between nodes are created using cypher queries and the same can be parsed from the RowStream
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let mut result = graph.execute( query("CREATE (p:Person { name: 'Oliver Stone' })-[r:WORKS_AT {as: 'Engineer'}]->(neo) RETURN r") ).await.unwrap(); let row = result.next().await.unwrap().unwrap(); let relation: Relation = row.get("r").unwrap(); assert!(relation.id() > -1); assert!(relation.start_node_id() > -1); assert!(relation.end_node_id() > -1); assert_eq!(relation.typ(), "WORKS_AT"); assert_eq!(relation.keys(), vec!["as"]); assert_eq!(relation.get::<String>("as").unwrap(), "Engineer"); } }Similar to bounded relation, an unbounded relation can also be created/parsed.
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let mut result = graph.execute( query("MERGE (p1:Person { name: 'Oliver Stone' })-[r:RELATED {as: 'friend'}]-(p2: Person {name: 'Mark'}) RETURN r") ).await.unwrap(); let row = result.next().await.unwrap().unwrap(); #[derive(serde::Deserialize)] struct Related { id: Id, start_node_id: StartNodeId, end_node_id: EndNodeId, typ: Type, keys: Keys<Vec<String>>, #[serde(rename = "as")] related_as: String, } // use serde to extract the relationship data let relation: Related = row.get("r").unwrap(); // The following checks are always true, but are included here // to demonstrate the types of the fields. #[allow(clippy::absurd_extreme_comparisons, unused_comparisons)] { assert!(relation.id.0 >= 0); assert!(relation.start_node_id.0 >= 0); assert!(relation.end_node_id.0 >= 0); } assert_eq!(relation.typ.0, "RELATED"); assert_eq!(relation.keys.0, vec!["as"]); assert_eq!(relation.related_as, "friend"); // or use the neo4rs::Relation type let relation: Relation = row.get("r").unwrap(); assert!(relation.id() > -1); assert!(relation.start_node_id() > -1); assert!(relation.end_node_id() > -1); assert_eq!(relation.typ(), "RELATED"); assert_eq!(relation.keys(), vec!["as"]); assert_eq!(relation.get::<String>("as").unwrap(), "friend"); } } §Points
A 2d or 3d point can be represented with the types Point2D and Point3D
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); let qry = " WITH point({ x: 2.3, y: 4.5, crs: 'cartesian' }) AS p1, point({ x: 1.1, y: 5.4, crs: 'cartesian' }) AS p2 RETURN point.distance(p1,p2) AS dist, p1, p2 "; { let mut result = graph.execute(query(qry)).await.unwrap(); let row = result.next().await.unwrap().unwrap(); let dist: f64 = row.get("dist").unwrap(); let p1: Point2D = row.get("p1").unwrap(); let p2: Point2D = row.get("p2").unwrap(); assert_eq!(1.5, dist); assert_eq!(p1.sr_id(), 7203); assert_eq!(p1.x(), 2.3); assert_eq!(p1.y(), 4.5); assert_eq!(p2.sr_id(), 7203); assert_eq!(p2.x(), 1.1); assert_eq!(p2.y(), 5.4); assert!(result.next().await.unwrap().is_none()); let mut result = graph .execute(query( "RETURN point({ longitude: 56.7, latitude: 12.78, height: 8 }) AS point", )) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let point: Point3D = row.get("point").unwrap(); assert_eq!(point.sr_id(), 4979); assert_eq!(point.x(), 56.7); assert_eq!(point.y(), 12.78); assert_eq!(point.z(), 8.0); assert!(result.next().await.unwrap().is_none()); } } §Raw bytes
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let bytes = b"Hello, Neo4j!"; let mut result = graph .execute(query("RETURN $b as output").param("b", bytes.as_ref())) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let b: Vec<u8> = row.get("output").unwrap(); assert_eq!(b, bytes); assert!(result.next().await.unwrap().is_none()); } } §Durations
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let duration = std::time::Duration::new(5259600, 7); let mut result = graph .execute(query("RETURN $d as output").param("d", duration)) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let d: std::time::Duration = row.get("output").unwrap(); assert_eq!(d.as_secs(), 5259600); assert_eq!(d.subsec_nanos(), 7); assert!(result.next().await.unwrap().is_none()); } } §Date
See NaiveDate for date abstraction, it captures the date without time component.
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let date = chrono::NaiveDate::from_ymd_opt(1985, 2, 5).unwrap(); let mut result = graph .execute(query("RETURN $d as output").param("d", date)) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let d: chrono::NaiveDate = row.get("output").unwrap(); assert_eq!(d.to_string(), "1985-02-05"); assert!(result.next().await.unwrap().is_none()); } }§Time
- NaiveTime captures only the time of the day
tuple(NaiveTime,Option<FixedOffset>) captures the time of the day along with the offset
§Time as param
Pass a time as a parameter to the query:
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { //send time without offset as param let time = chrono::NaiveTime::from_hms_nano_opt(11, 15, 30, 200).unwrap(); let mut result = graph .execute(query("RETURN $d as output").param("d", time)) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: (chrono::NaiveTime, Option<Offset>) = row.get("output").unwrap(); assert_eq!(t.0.to_string(), "11:15:30.000000200"); assert_eq!(t.1, None); assert!(result.next().await.unwrap().is_none()); //send time with offset as param let time = chrono::NaiveTime::from_hms_nano_opt(11, 15, 30, 200).unwrap(); let offset = chrono::FixedOffset::east_opt(3 * 3600).unwrap(); let mut result = graph .execute(query("RETURN $d as output").param("d", (time, offset))) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: (chrono::NaiveTime, Option<Offset>) = row.get("output").unwrap(); assert_eq!(t.0.to_string(), "11:15:30.000000200"); assert_eq!(t.1, Some(Offset(offset))); assert!(result.next().await.unwrap().is_none()); } }§Parsing time from result
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { //Parse time without offset let mut result = graph .execute(query( " WITH time({hour:10, minute:15, second:30, nanosecond: 200}) AS t RETURN t", )) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: (chrono::NaiveTime, Option<Offset>) = row.get("t").unwrap(); assert_eq!(t.0.to_string(), "10:15:30.000000200"); assert_eq!(t.1, None); assert!(result.next().await.unwrap().is_none()); //Parse time with timezone information let mut result = graph .execute(query( " WITH time({hour:10, minute:15, second:33, nanosecond: 200, timezone: '+01:00'}) AS t RETURN t", )) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: (chrono::NaiveTime, Option<Offset>) = row.get("t").unwrap(); assert_eq!(t.0.to_string(), "10:15:33.000000200"); assert_eq!(t.1, Some(Offset(chrono::FixedOffset::east_opt(3600).unwrap()))); assert!(result.next().await.unwrap().is_none()); } } §DateTime
- DateTime captures the date and time with offset
- NaiveDateTime captures the date time without offset
tuple(NaiveDateTime, String) captures the date/time and the time zone id
§DateTime as param
Pass a DateTime as parameter to the query:
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { //send datetime as parameter in the query let datetime = chrono::DateTime::parse_from_rfc2822("Tue, 01 Jul 2003 10:52:37 +0200").unwrap(); let mut result = graph .execute(query("RETURN $d as output").param("d", datetime)) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: chrono::DateTime<chrono::FixedOffset> = row.get("output").unwrap(); assert_eq!(t.to_string(), "2003-07-01 10:52:37 +02:00"); assert!(result.next().await.unwrap().is_none()); //send NaiveDateTime as parameter in the query let localdatetime = chrono::NaiveDateTime::parse_from_str("2015-07-01 08:55:59.123", "%Y-%m-%d %H:%M:%S%.f") .unwrap(); let mut result = graph .execute(query("RETURN $d as output").param("d", localdatetime)) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: chrono::NaiveDateTime = row.get("output").unwrap(); assert_eq!(t.to_string(), "2015-07-01 08:55:59.123"); assert!(result.next().await.unwrap().is_none()); //send NaiveDateTime with timezone id as parameter in the query let datetime = chrono::NaiveDateTime::parse_from_str("2015-07-03 08:55:59.555", "%Y-%m-%d %H:%M:%S%.f") .unwrap(); let timezone = "Europe/Paris"; let mut result = graph .execute(query("RETURN $d as output").param("d", (datetime, timezone))) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let (time, zone): (chrono::NaiveDateTime, String) = row.get("output").unwrap(); assert_eq!(time.to_string(), "2015-07-03 08:55:59.555"); assert_eq!(zone, "Europe/Paris"); assert!(result.next().await.unwrap().is_none()); } }§Parsing DateTime from result
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { //Parse NaiveDateTime from result let mut result = graph .execute(query( "WITH localdatetime('2015-06-24T12:50:35.556') AS t RETURN t", )) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: chrono::NaiveDateTime = row.get("t").unwrap(); assert_eq!(t.to_string(), "2015-06-24 12:50:35.556"); assert!(result.next().await.unwrap().is_none()); //Parse DateTime from result let mut result = graph .execute(query( "WITH datetime('2015-06-24T12:50:35.777+0100') AS t RETURN t", )) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let t: chrono::DateTime<chrono::FixedOffset> = row.get("t").unwrap(); assert_eq!(t.to_string(), "2015-06-24 12:50:35.777 +01:00"); assert!(result.next().await.unwrap().is_none()); //Parse NaiveDateTime with zone id from result let mut result = graph .execute(query( "WITH datetime({ year:1984, month:11, day:11, hour:12, minute:31, second:14, nanosecond: 645876123, timezone:'Europe/Stockholm' }) AS d return d", )) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let (datetime, zone_id): (chrono::NaiveDateTime, String) = row.get("d").unwrap(); assert_eq!(datetime.to_string(), "1984-11-11 12:31:14.645876123"); assert_eq!(zone_id, "Europe/Stockholm"); assert!(result.next().await.unwrap().is_none()); } } §Path
use neo4rs::*; #[tokio::main] async fn main() { let uri = "127.0.0.1:7687"; let user = "neo4j"; let pass = "neo"; let graph = Graph::new(uri, user, pass).await.unwrap(); { let name = uuid::Uuid::new_v4().to_string(); graph .run( query("CREATE (p:Person { name: $name })-[r:WORKS_AT]->(n:Company { name: 'Neo'})") .param("name", name.clone()), ) .await .unwrap(); let mut result = graph .execute( query("MATCH p = (person:Person { name: $name })-[r:WORKS_AT]->(c:Company) RETURN p") .param("name", name), ) .await .unwrap(); let row = result.next().await.unwrap().unwrap(); let path: Path = row.get("p").unwrap(); assert_eq!(path.indices().len(), 2); assert_eq!(path.nodes().len(), 2); assert_eq!(path.rels().len(), 1); assert!(result.next().await.unwrap().is_none()); } }Macros§
Structs§
- Bolt
Boolean - Bolt
Bytes - Bolt
Date - Bolt
Date Time - Bolt
Date Time Zone Id - Bolt
Duration - Bolt
Float - Bolt
Integer - Bolt
List - Bolt
Local Date Time - Bolt
Local Time - BoltMap
- Bolt
Node - Bolt
Null - Bolt
Path - Bolt
Point2D - Bolt
Point3D - Bolt
Relation - Bolt
String - Bolt
Time - Bolt
Unbounded Relation - Client
Certificate - Config
- The configuration used to connect to the database, see
crate::Graph::connect. - Config
Builder - A builder to override default configurations and build the
Config. - Database
- Newtype for the name of the database. Stores the name as an
Arc<str>to avoid cloning the name around. - EndNode
Id - Newtype to extract the end node id of a relationship during deserialization.
- Graph
- A neo4j database abstraction. This type can be cloned and shared across threads, internal resources are reference-counted.
- Id
- Newtype to extract the node id or relationship id during deserialization.
- Indices
- Newtype to extract the indices of a path during deserialization.
- Keys
- Newtype to extract the node property keys during deserialization.
- Labels
- Newtype to extract the node labels during deserialization.
- Neo4j
Error - Node
- Snapshot of a node within a graph database
- Nodes
- Newtype to extract the nodes of a path during deserialization.
- Offset
- Newtype to extract the offset info of times during deserialization.
- Path
- Alternating sequence of nodes and relationships
- Point2D
- Represents a single location in 2-dimensional space
- Point3D
- Represents a single location in 3-dimensional space
- Query
- Abstracts a cypher query that is sent to neo4j server.
- Relation
- Snapshot of a relationship within a graph database
- Relationships
- Newtype to extract the relationships of a path during deserialization.
- Row
- Represents a row returned as a result of executing a query.
- RowStream
- An abstraction over a stream of rows, this is returned as a result of
crate::Txn::execute. - Start
Node Id - Newtype to extract the start node id of a relationship during deserialization.
- Timezone
- Newtype to extract the timezone info of datetimes during deserialization.
- Txn
- A handle which is used to control a transaction, created as a result of
crate::Graph::start_txn - Type
- Newtype to extract the relationship type during deserialization.
- Unbounded
Relation - Relationship detail without start or end node information
Enums§
Functions§
- query
- Returns a
Querywhich provides methods likeQuery::paramto add parameters to the query - unexpected