rustsurrealdb

Surrealdb Rust SDK select function not working as in Documentation


While using the Rust SDK for Surrealdb, where i don't know what i do different compared to the official documentation. Selecting all records from a table works fine, however selecting a specified record doesn't give me a result.

Working Example selecting all records in the table

here self.db is a Surreal<Client>:

pub async fn get_all_sensors(&self) -> Result<Vec<Sensor>, SDBError>{
    let response_data: Result<Vec<Sensor>, surrealdb::Error> = self.db.select("sensor").await;
    match response_data {
        Ok(response_data) => Ok(response_data),
        Err(_) => Err(SDBError)
        }
}

which will give me the following result:

[
    {
        "uuid": "foo"
    }
]

however trying to select only the "foo" entry like the following:

pub async fn get_sensor(&self, sensor: Sensor) -> Option<Sensor>{
    let response: Result<Option<Sensor>, surrealdb::Error> = self.db.select(("sensor", "foo")).await;
     match response {
         Ok(output) => output,
         Err(_) => None,
}

in Surrealist i can see that the entry also has the right "id".

{
    "id": "sensor:foo",
    "uuid": "foo"
}

Implementation is very similar to the Documentation: Surrealdb Rust SDK Only difference is that i don't use the await? but awaitthen matching the Result manually.

Also tried out the version (for testing) with self.db.select("sensor", "foo").range((Bound::Included(""), Bound::Exluded("foo")).await.unwrap() as they have done it in their tests Surrealdb Github Test on Line 131.

One difference that I can see is that they use a Lazy<Surreal<Client>> but I don't see that as the problem.


Solution

  • I tried to reproduce your example as closely as possible but I can't get the same result. I first created the record using

    CREATE sensor:foo SET uuid = "foo";
    

    and then ran the following code

    use serde::Deserialize;
    use surrealdb::engine::remote::ws::{Client, Ws};
    use surrealdb::opt::auth::Root;
    use surrealdb::opt::RecordId;
    use surrealdb::Surreal;
    
    struct Db {
            db: Surreal<Client>,
    }
    
    #[derive(Debug, Deserialize)]
    struct Sensor {
            id: RecordId,
            uuid: String,
    }
    
    impl Db {
            async fn get_sensor(&self) -> Option<Sensor> {
                    let response: Result<Option<Sensor>, surrealdb::Error> =
                            self.db.select(("sensor", "foo")).await;
                    match response {
                            Ok(output) => output,
                            Err(_) => None,
                    }
            }
    }
    
    #[tokio::main]
    async fn main() -> surrealdb::Result<()> {
            let db = Surreal::new::<Ws>("localhost:8000").await?;
    
            db.signin(Root {
                    username: "root",
                    password: "root",
            })
            .await?;
    
            db.use_ns("test").use_db("test").await?;
    
            let db = Db {
                    db,
            };
    
            let sensor = db.get_sensor().await;
    
            println!("{sensor:?}");
    
            Ok(())
    }
    

    This prints

    Some(Sensor { id: Thing { tb: "sensor", id: String("foo") }, uuid: "foo" })
    

    In my case both the surrealdb crate and server are on v1.0.0. Which versions are you using for both?

    Also tried out the version (for testing) with self.db.select("sensor", "foo").range((Bound::Included(""), Bound::Exluded("foo")).await.unwrap()

    self.db.select("sensor", "foo") shouldn't compile. That method only takes one argument.

    .range((Bound::Included(""), Bound::Exluded("foo")) tells the database to return all records whose id starts from "" up to but not including "foo", sorted by id. This can be written simply as .range("".."foo"). As you may expect, this method only works with queries that return multiple results. If you try to use it with something that fetches a specific record like db.select(("sensor", "foo")) you will get an error.