Search code examples
postgresqlrustfull-text-searchrust-diesel

how to using rust diesel to do the full text query


I am trying to using diesel diesel = { version = "1.4.8", features = ["postgres","64-column-tables","chrono","serde_json"] } to do a full text query, this is the sql command look like:

SELECT * FROM article a  WHERE to_tsvector('english', title) @@ to_tsquery('english','Rate|Limiting')

how to using rust diesel to do this query? I am using the like right now and want to switch to full text search, this is the like query code main.rs look like:

#[macro_use]
extern crate diesel;

use diesel::{TextExpressionMethods, QueryDsl, RunQueryDsl};
use rust_wheel::config::db::config;
use crate::model::diesel::dict::dict_models::Article;

mod model;

fn main() {
    use model::diesel::dict::dict_schema::article as article_table;
    let connection = config::establish_connection();
    let mut query = article_table::table.into_boxed::<diesel::pg::Pg>();
    query = query.filter(article_table::title.like(format!("{}{}{}","%","demo","%")));
    let query_result = query.load::<Article>(&connection);
}

and this is the schema files dict_schema.rs look like:

table! {
    article (id) {
        id -> Int8,
        user_id -> Int8,
        title -> Varchar,
        author -> Varchar,
        guid -> Varchar,
        created_time -> Int8,
        updated_time -> Int8,
        link -> Nullable<Varchar>,
        sub_source_id -> Int8,
        cover_image -> Nullable<Varchar>,
        channel_reputation -> Int4,
        editor_pick -> Nullable<Int4>,
    }
}

and this is the model files dict_models.rs look like:

// Generated by diesel_ext

#![allow(unused)]
#![allow(clippy::all)]

use std::io::Write;
use diesel::deserialize::FromSql;
use diesel::pg::Pg;
use diesel::serialize::{Output, ToSql};
use diesel::sql_types::Jsonb;
use rocket::serde::Serialize;
use serde::Deserialize;
use chrono::DateTime;
use chrono::Utc;
use crate::model::diesel::dict::dict_schema::*;

#[derive(Queryable,QueryableByName,Debug,Serialize,Deserialize,Default,Clone)]
#[table_name = "article"]
pub struct Article {
    pub id: i64,
    pub user_id: i64,
    pub title: String,
    pub author: String,
    pub guid: String,
    pub created_time: i64,
    pub updated_time: i64,
    pub link: Option<String>,
    pub sub_source_id: i64,
    pub cover_image: Option<String>,
    pub channel_reputation: i32,
    pub editor_pick: Option<i32>,
}

and this is the dependencies Cargo.toml look like:

[package]
name = "rust-learn"
version = "0.1.0"
edition = "2018"

[dependencies]
rocket = { version = "=0.5.0-rc.2", features = ["json"] }

serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
serde_derive = "1.0"
# database
diesel = { version = "1.4.7", features = ["postgres","serde_json"] }
dotenv = "0.15.0"
jsonwebtoken = "7"
chrono = "0.4"
config = "0.11"
ring = "0.16.20"
md5 = "0.7.0"
data-encoding = "2.3.2"
diesel_full_text_search = "1.0.1"
bigdecimal = "0.3.0"
# reddwarf public component
rust_wheel = { git = "https://github.com/jiangxiaoqiang/rust_wheel.git" }

What shuld I do to change to like query to full text search query? I am searching from internet but no one talk about this issue. BTW: this is the cargo version:

➜  rust-learn git:(group-by) ✗ cargo version
cargo 1.62.0 (a748cf5a3 2022-06-08)

and this is the rust version:

➜  rust-learn git:(group-by) ✗ rustc --version
rustc 1.62.0 (a8314ef7d 2022-06-27)

any idea about this issue? what should i do to using the full text search in diesel?

I have tried to add the dependencies diesel_full_text_search = "1.0.1" and tweak the main.rs code like this:

#[macro_use]
extern crate diesel;

use diesel::{TextExpressionMethods, QueryDsl, RunQueryDsl};
use diesel_full_text_search::{to_tsquery, to_tsvector, TsQueryExtensions};
use rust_wheel::config::db::config;
use diesel_full_text_search::TsVectorExtensions;
use crate::model::diesel::dict::dict_models::Article;

mod model;

fn main() {
    use model::diesel::dict::dict_schema::article as article_table;
    let connection = config::establish_connection();
    let mut query = article_table::table.into_boxed::<diesel::pg::Pg>();
    let filter_title = "经济 文化";
    let query_items: Vec<&str> = filter_title.trim().split_whitespace().collect();
    let query_array = query_items.join(" & ");
    let tsquery = to_tsquery(query_array);
    let tsvector = to_tsvector("'dolphinzhcfg', title");
    query = query.filter(&tsvector.matches(&tsquery));
    let query_result = query.load::<Article>(&connection);
}

shows error:

mismatched types [E0308] expected `char`, found `&to_tsquery<String>`

what should I do to fixed this problem?


Solution

  • Checkout the following functions: