How to do a IN query using diesel?

Viewed 870

I want to do an IN query with diesel using PostgreSQL 13 to select songs collection from songs table in some id collections. The SQL executed by the database may look like this:

select * from songs where id in(1,2,3)

what I tried to do using rust diesel way like this:

pub fn songs(ids: Vec<i64>){
    use schema::songs::dsl::*;
    let connection = config::establish_connection();
    let results = songs.filter(id.contains(ids))
        .load::<QuerySongs>(&connection)
        .expect("Error loading posts");
}

seems did not work, when I compile the project code using cargo build shows error like this:

error[E0599]: the method `contains` exists for struct `songs::schema::songs::columns::id`, but its trait bounds were not satisfied
  --> src/biz/music/songs.rs:37:35
   |
37 |       let results = songs.filter(id.contains(ids))
   |                                     ^^^^^^^^ method cannot be called on `songs::schema::songs::columns::id` due to unsatisfied trait bounds

I read the docs and source code demo but it was so short and did not mention about how to execute a query by id in a collection. What should I do to make a IN query in rust diesel(diesel = { version = "1.4.4", features = ["postgres"] })? Here is a minimal reproducible demo.

1 Answers

You're looking for .eq_any(). But heed the documentation:

Creates a SQL IN statement.

Queries using this method will not be placed in the prepared statement cache. On PostgreSQL, you should use eq(any()) instead. This method may change in the future to automatically perform = ANY on PostgreSQL.

So using .eq() and any() your code should look something like:

let results = songs.filter(id.eq(any(ids)))
    .load::<QuerySongs>(&connection)
    .expect("Error loading posts");
Related