v0.12-searchP1

This commit is contained in:
2022-11-13 17:47:53 +05:30
parent dfa83b68b0
commit 875b826f0b
9 changed files with 323 additions and 147 deletions

283
backend/Cargo.lock generated
View File

@@ -82,6 +82,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "arrayvec"
version = "0.7.2"
@@ -426,6 +432,7 @@ dependencies = [
"axum",
"axum-extra",
"booksman-orm",
"booksman-search",
"clap",
"dotenvy",
"entity",
@@ -454,6 +461,15 @@ dependencies = [
"serde",
]
[[package]]
name = "booksman-search"
version = "0.1.0"
dependencies = [
"meilisearch-sdk",
"serde",
"tokio",
]
[[package]]
name = "brotli"
version = "3.3.4"
@@ -505,6 +521,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
[[package]]
name = "castaway"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6"
[[package]]
name = "cc"
version = "1.0.73"
@@ -716,6 +738,37 @@ dependencies = [
"syn",
]
[[package]]
name = "curl"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
dependencies = [
"curl-sys",
"libc",
"openssl-probe",
"openssl-sys",
"schannel",
"socket2",
"winapi",
]
[[package]]
name = "curl-sys"
version = "0.4.59+curl-7.86.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407"
dependencies = [
"cc",
"libc",
"libnghttp2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
"winapi",
]
[[package]]
name = "digest"
version = "0.10.3"
@@ -767,6 +820,9 @@ name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
dependencies = [
"serde",
]
[[package]]
name = "encoding_rs"
@@ -1292,7 +1348,43 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78"
dependencies = [
"nom",
"nom 7.1.1",
]
[[package]]
name = "isahc"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9"
dependencies = [
"async-channel",
"castaway",
"crossbeam-utils",
"curl",
"curl-sys",
"encoding_rs",
"event-listener",
"futures-lite",
"http",
"log",
"mime",
"once_cell",
"polling",
"slab",
"sluice",
"tracing",
"tracing-futures",
"url",
"waker-fn",
]
[[package]]
name = "iso8601-duration"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b51dd97fa24074214b9eb14da518957573f4dec3189112610ae1ccec9ac464"
dependencies = [
"nom 5.1.2",
]
[[package]]
@@ -1328,6 +1420,18 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonwebtoken"
version = "8.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aa4b4af834c6cfd35d8763d359661b90f2e45d8f750a0849156c7f4671af09c"
dependencies = [
"base64",
"ring",
"serde",
"serde_json",
]
[[package]]
name = "kv-log-macro"
version = "1.0.7"
@@ -1349,12 +1453,35 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec 0.5.2",
"bitflags",
"cfg-if",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]]
name = "libnghttp2-sys"
version = "0.1.7+1.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "libsqlite3-sys"
version = "0.24.2"
@@ -1366,6 +1493,18 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "lock_api"
version = "0.4.8"
@@ -1416,6 +1555,30 @@ dependencies = [
"digest",
]
[[package]]
name = "meilisearch-sdk"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c0fab01f198149ac68362c48d2b332d3b0ce0a0241765fb430ea443c5d361e2"
dependencies = [
"async-trait",
"either",
"futures",
"isahc",
"iso8601-duration",
"js-sys",
"jsonwebtoken",
"log",
"serde",
"serde_json",
"time 0.3.14",
"uuid",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"yaup",
]
[[package]]
name = "memchr"
version = "2.5.0"
@@ -1519,6 +1682,17 @@ dependencies = [
"tempfile",
]
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "nom"
version = "7.1.1"
@@ -2057,7 +2231,7 @@ version = "1.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee9164faf726e4f3ece4978b25ca877ddc6802fa77f38cdccb32c7f805ecd70c"
dependencies = [
"arrayvec",
"arrayvec 0.7.2",
"num-traits",
"serde",
]
@@ -2068,27 +2242,6 @@ version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustls"
version = "0.20.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55"
dependencies = [
"base64",
]
[[package]]
name = "rustversion"
version = "1.0.9"
@@ -2123,16 +2276,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "sea-orm"
version = "0.9.2"
@@ -2395,6 +2538,17 @@ dependencies = [
"autocfg",
]
[[package]]
name = "sluice"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5"
dependencies = [
"async-channel",
"futures-core",
"futures-io",
]
[[package]]
name = "smallvec"
version = "1.9.0"
@@ -2433,7 +2587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4"
dependencies = [
"itertools",
"nom",
"nom 7.1.1",
"unicode_categories",
]
@@ -2483,8 +2637,6 @@ dependencies = [
"paste",
"percent-encoding",
"rust_decimal",
"rustls",
"rustls-pemfile",
"serde",
"serde_json",
"sha2",
@@ -2497,7 +2649,6 @@ dependencies = [
"tokio-stream",
"url",
"uuid",
"webpki-roots",
]
[[package]]
@@ -2530,9 +2681,14 @@ dependencies = [
"once_cell",
"tokio",
"tokio-native-tls",
"tokio-rustls",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "stringprep"
version = "0.1.2"
@@ -2670,6 +2826,7 @@ dependencies = [
"itoa",
"libc",
"num_threads",
"serde",
"time-macros",
]
@@ -2736,17 +2893,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls",
"tokio",
"webpki",
]
[[package]]
name = "tokio-stream"
version = "0.1.9"
@@ -2864,6 +3010,16 @@ dependencies = [
"valuable",
]
[[package]]
name = "tracing-futures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
dependencies = [
"pin-project",
"tracing",
]
[[package]]
name = "tracing-log"
version = "0.1.3"
@@ -3107,25 +3263,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf"
dependencies = [
"webpki",
]
[[package]]
name = "weezl"
version = "0.1.7"
@@ -3223,3 +3360,13 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]
[[package]]
name = "yaup"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a59e7d27bed43f7c37c25df5192ea9d435a8092a902e02203359ac9ce3e429d9"
dependencies = [
"serde",
"url",
]

View File

@@ -5,7 +5,7 @@ edition = "2021"
[workspace]
members = [".", "entity", "migration", "orm", "api"]
members = [".", "entity", "migration", "orm", "search", "api"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
booksman-orm = { path = "../orm" }
booksman-search = { path = "../search" }
entity = { path = "../entity" }
axum = "^0.5"
axum-extra = { version = "^0.3", features = ["spa"] }

View File

@@ -269,38 +269,33 @@ async fn list_book(
.await
.expect("could not list books");
let mut data_grouped: Vec<(i32,Vec<BookAndMeta>)> = Vec::with_capacity(5);
for (key, group) in &books.0.into_iter().group_by(|x| x.id) {
data_grouped.push((key, group.collect()));
}
let mut resbooks: Vec<BookUI> = Vec::with_capacity(5);
for (id,group) in data_grouped.into_iter() {
let mut cover = group.clone().into_iter().clone().map(|u| u.cover).next();
for bookandmeta in books.0.into_iter() {
let mut cover = bookandmeta.clone().book.cover;
if !cover.is_none() {
cover = Some(format!("http://localhost:8081/images/{}",cover.unwrap()));
cover = Some(format!("http://localhost:8081/images/{}",cover.unwrap()));
}
let bookui = BookUI{
id,
title: group.clone().into_iter().map( |u| u.title).next().unwrap(),
open_library_key: group.clone().into_iter().map( |u| u.open_library_key).next(),
edition_count: group.clone().into_iter().clone().map(|u| u.edition_count).next(),
first_publish_year: group.clone().into_iter().clone().map(|u| u.first_publish_year).next(),
median_page_count: group.clone().into_iter().clone().map(|u| u.median_page_count).next(),
goodread_id: group.clone().into_iter().clone().map(|u| u.goodread_id).next(),
description: group.clone().into_iter().clone().map(|u| u.description).next(),
cover: cover.clone(),
location: group.clone().into_iter().clone().map(|u| u.location).next(),
time_added: group.clone().into_iter().clone().map(|u| u.time_added).next(),
rating: group.clone().into_iter().clone().map(|u| u.rating).next(),
comments: group.clone().into_iter().clone().map(|u| u.comments).next(),
author_name: Some(group.clone().into_iter().map(|u| u.author_name).collect()),
person: Some(group.clone().into_iter().map(|u| u.person).collect()),
place: Some(group.clone().into_iter().map(|u| u.place).collect()),
subject: Some(group.clone().into_iter().map(|u| u.subject).collect()),
time: Some(group.clone().into_iter().map(|u| u.time).collect()),
isbn: Some(group.clone().into_iter().map(|u| u.isbn).collect()),
id: bookandmeta.clone().book.id,
title: bookandmeta.clone().book.title,
open_library_key: bookandmeta.clone().book.open_library_key,
edition_count: bookandmeta.clone().book.edition_count,
first_publish_year: bookandmeta.clone().book.first_publish_year,
median_page_count: bookandmeta.clone().book.median_page_count,
goodread_id: bookandmeta.clone().book.goodread_id,
description: bookandmeta.clone().book.description,
cover: cover.clone(),
location: bookandmeta.clone().book.location,
time_added: bookandmeta.clone().book.time_added,
rating: bookandmeta.clone().book.rating,
comments: bookandmeta.clone().book.comments,
author_name: Some(bookandmeta.clone().authors.into_iter().map(|u| u.author_name).collect() ),
person: Some(bookandmeta.clone().persons.into_iter().map(|u| u.person).collect()),
place: Some(bookandmeta.clone().places.into_iter().map(|u| u.place).collect()),
subject: Some(bookandmeta.clone().subjects.into_iter().map(|u| u.subject).collect()),
time: Some(bookandmeta.clone().times.into_iter().map(|u| u.time).collect()),
isbn: Some(bookandmeta.clone().isbns.into_iter().map(|u| u.isbn).collect()),
};
resbooks.push(bookui);
}
@@ -309,30 +304,6 @@ isbn: Some(group.clone().into_iter().map(|u| u.isbn).collect()),
num_pages: books.1 as u32,
books: resbooks
};
/* let mut res: Vec<BookUI> = (books.0).iter()
.group_by(|x| (x.id, x.title.clone()) ).into_iter()
.map(|((id,title), group )| BookUI{
id,
title,
open_library_key: group.map( |u| u.open_library_key.clone()).next(),
edition_count: group.map(|u| u.edition_count).next(),
first_publish_year: group.map(|u| u.first_publish_year).next(),
median_page_count: group.map(|u| u.median_page_count).next(),
goodread_id: group.map(|u| u.goodread_id.clone()).next(),
description: group.map(|u| u.description.clone()).next(),
cover: group.map(|u| u.cover.clone()).next(),
location: group.map(|u| u.location.clone()).next(),
time_added: group.map(|u| u.time_added.clone()).next(),
rating: group.map(|u| u.rating).next(),
comments: group.map(|u| u.comments.clone()).next(),
author_name: Some(group.map(|u| u.author_name.clone()).collect()),
person: Some(group.map(|u| u.person.clone()).collect()),
place: Some(group.map(|u| u.place.clone()).collect()),
subject: Some(group.map(|u| u.subject.clone()).collect()),
time: Some(group.map(|u| u.time.clone()).collect()),
isbn: Some(group.map(|u| u.isbn.clone()).collect()),
}).collect();
*/
return Json(res);
// "success"
}

View File

@@ -18,6 +18,6 @@ features = [
# Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
# View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
# e.g.
"runtime-tokio-rustls", # `ASYNC_RUNTIME` feature
"runtime-tokio-native-tls", # `ASYNC_RUNTIME` feature
"sqlx-sqlite", # `DATABASE_DRIVER` feature
]

View File

@@ -27,6 +27,18 @@ pub struct BookAndMeta {
pub time: String,
pub isbn: String,
}
#[derive(Clone)]
pub struct BookAndMetaV2 {
pub book: book::Model,
pub authors: Vec<book_author::Model>,
pub persons: Vec<book_person::Model>,
pub places: Vec<book_place::Model>,
pub subjects: Vec<book_subject::Model>,
pub times: Vec<book_time::Model>,
pub isbns: Vec<book_isbn::Model>,
}
//use ::entity::entities::prelude::Book;
pub struct Query;
@@ -64,33 +76,33 @@ pub async fn find_books_plus_meta_in_page(
db: &DbConn,
page: usize,
posts_per_page: usize,
) -> Result<(Vec<BookAndMeta>, usize), DbErr> {
) -> Result<(Vec<BookAndMetaV2>, usize), DbErr> {
// Setup paginator
let books = Self::find_books_in_page(db,page,posts_per_page).await?;
let book_ids: Vec<i32> = books.0.clone().into_iter().map(|b| b.id).collect();
/* let paginator1 = Book::find().filter(
Condition::any()
.add(book::Column::Id.is_in(book_ids))
).find_with_related(Author).all(db).await?;*/
let paginator2: Vec<BookAndMeta> = Book::find()
.filter(Condition::any()
.add(book::Column::Id.is_in(book_ids)))
.join(JoinType::LeftJoin, book::Relation::BookAuthor.def())
.join(JoinType::LeftJoin, book::Relation::BookPerson.def())
.join(JoinType::LeftJoin, book::Relation::BookPlace.def())
.join(JoinType::LeftJoin, book::Relation::BookSubject.def())
.join(JoinType::LeftJoin, book::Relation::BookTime.def())
.join(JoinType::LeftJoin, book::Relation::BookIsbn.def())
.column_as(book_author::Column::AuthorName, "author_name")
.column_as(book_person::Column::Person, "person")
.column_as(book_place::Column::Place, "place")
.column_as(book_subject::Column::Subject, "subject")
.column_as(book_time::Column::Time, "time")
.column_as(book_isbn::Column::Isbn, "isbn")
.into_model::<BookAndMeta>()
.all(db).await?;
let mut resbooks: Vec<BookAndMetaV2> = Vec::with_capacity(book_ids.len());
for book in books.0.iter() {
let bauthors: Vec<book_author::Model> = book.find_related(book_author::Entity).all(db).await?;
let bpersons: Vec<book_person::Model> = book.find_related(book_person::Entity).all(db).await?;
let bplaces: Vec<book_place::Model> = book.find_related(book_place::Entity).all(db).await?;
let bsubjects: Vec<book_subject::Model> = book.find_related(book_subject::Entity).all(db).await?;
let btimes: Vec<book_time::Model> = book.find_related(book_time::Entity).all(db).await?;
let bisbns: Vec<book_isbn::Model> = book.find_related(book_isbn::Entity).all(db).await?;
Ok((paginator2,books.1))
let bookandmeta = BookAndMetaV2 {
book: (book.clone()),
authors: bauthors,
persons: bpersons,
places: bplaces,
subjects: bsubjects,
times: btimes,
isbns: bisbns
};
resbooks.push(bookandmeta);
}
Ok((resbooks,books.1))
}
}

11
backend/search/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "booksman-search"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
serde = { version = "1", features = ["derive"] }
meilisearch-sdk = "0.20.1"
tokio = { version = "^1", features = ["full"] }

30
backend/search/src/lib.rs Normal file
View File

@@ -0,0 +1,30 @@
use meilisearch_sdk::{client::*, search::*};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct Movie {
id: usize,
title: String,
genres: Vec<String>,
}
#[tokio::main]
async fn main() {
// Create a client (without sending any request so that can't fail)
let client = Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
// An index is where the documents are stored.
let movies = client.index("movies");
// Add some movies in the index. If the index 'movies' does not exist, Meilisearch creates it when you first add the documents.
movies.add_documents(&[
Movie { id: 1, title: String::from("Carol"), genres: vec!["Romance".to_string(), "Drama".to_string()] },
Movie { id: 2, title: String::from("Wonder Woman"), genres: vec!["Action".to_string(), "Adventure".to_string()] },
Movie { id: 3, title: String::from("Life of Pi"), genres: vec!["Adventure".to_string(), "Drama".to_string()] },
Movie { id: 4, title: String::from("Mad Max"), genres: vec!["Adventure".to_string(), "Science Fiction".to_string()] },
Movie { id: 5, title: String::from("Moana"), genres: vec!["Fantasy".to_string(), "Action".to_string()] },
Movie { id: 6, title: String::from("Philadelphia"), genres: vec!["Drama".to_string()] },
], Some("id")).await.unwrap();
}

View File

@@ -51,7 +51,9 @@ pub struct AppState {
pub openlibrary: RcSignal<bool>,
pub adding: RcSignal<bool>,
pub updating: RcSignal<bool>,
pub displaying: RcSignal<bool>,
pub addingbook: RcSignal<BookUI>,
pub displayingbook: RcSignal<BookUI>,
}
#[derive(Route)]
@@ -413,6 +415,8 @@ fn App<G: Html>(cx: Scope) -> View<G> {
adding: create_rc_signal(bool::default()),
updating: create_rc_signal(bool::default()),
addingbook: create_rc_signal(BookUI::default()),
displaying: create_rc_signal(bool::default()),
displayingbook: create_rc_signal(BookUI::default()),
};
provide_context(cx, app_state);
view! {