diff --git a/Cargo.toml b/Cargo.toml index 1f8ea73d0..82c2ac76b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ serde_json = "1.0" serde = {version="1.0", features=["derive"]} meilisearch-sdk = "0.1.3" actix-files = "0.2.1" -chrono = "0.4.11" human_format = "1.0.3" reqwest = "0.10.4" log = "0.4.8" diff --git a/src/routes/search.rs b/src/routes/search.rs index c1c3920fd..553482e45 100644 --- a/src/routes/search.rs +++ b/src/routes/search.rs @@ -10,6 +10,7 @@ use meilisearch_sdk::settings::Settings; use mongodb::error::Error; use bson::Bson; use mongodb::Cursor; +use std::collections::HashMap; #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] @@ -51,7 +52,7 @@ struct CurseForgeMod { date_modified: String, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] struct SearchMod { mod_id: i32, author: String, @@ -64,7 +65,9 @@ struct SearchMod { icon_url: String, author_url: String, date_created: String, + created: i32, date_modified: String, + updated: i32, latest_version: String, empty: String, } @@ -83,6 +86,7 @@ pub struct SearchRequest { f: Option, v: Option, o: Option, + s: Option, } #[post("search")] @@ -120,9 +124,10 @@ pub async fn search_get( fn search(web::Query(info): web::Query) -> Vec { let client = Client::new("http://localhost:7700", ""); - let search_query: String; + let mut search_query: String; let mut filters = "".to_string(); let mut offset = 0; + let mut index = "relevance".to_string(); match info.q { Some(q) => search_query = q, @@ -145,6 +150,10 @@ fn search(web::Query(info): web::Query) -> Vec { offset = o.parse().unwrap(); } + if let Some(s) = info.s { + index = s; + } + let mut query = Query::new(&search_query).with_limit(10).with_offset(offset); if !filters.is_empty() { @@ -152,22 +161,26 @@ fn search(web::Query(info): web::Query) -> Vec { } client - .get_index("mods") + .get_index(format!("{}_mods", index).as_ref()) .unwrap() .search::(&query) .unwrap() .hits } +/* +TODO This method needs a lot of refactoring. Here's a list of changes that need to be made: + - Move Curseforge Indexing to another method/module + - Get rid of the 4 indexes (when MeiliSearch updates) and replace it with different rules + - Cleanup this code (it's very messy) + */ + pub async fn index_mods(conn: mongodb::Client) -> Result<(), Error>{ let client = Client::new("http://localhost:7700", ""); - let mut mods_index = client.get_or_create("mods").unwrap(); - let mut docs_to_add: Vec = vec![]; info!("Indexing database mods!"); - info!("Indexing curseforge mods!"); let body = reqwest::get("https://addons-ecs.forgesvc.net/api/v2/addon/search?categoryId=0&gameId=432&index=0&pageSize=10000§ionId=6&sort=5") @@ -276,28 +289,15 @@ pub async fn index_mods(conn: mongodb::Client) -> Result<(), Error>{ icon_url: (mod_attachments[0].url).to_string(), author_url: (&curseforge_mod.authors[0].url).to_string(), date_created: curseforge_mod.date_created.chars().take(10).collect(), + created: curseforge_mod.date_created.chars().filter(|c| c.is_ascii_digit()).collect::().parse().unwrap(), date_modified: curseforge_mod.date_modified.chars().take(10).collect(), + updated: curseforge_mod.date_modified.chars().filter(|c| c.is_ascii_digit()).collect::().parse().unwrap(), latest_version, empty: String::from("{}{}{}"), }) } - mods_index - .add_documents(docs_to_add, Some("mod_id")) - .unwrap(); - //Write Settings - let settings = mods_index.get_settings().unwrap(); - - let ranking_rules = vec![ - "typo".to_string(), - "words".to_string(), - "proximity".to_string(), - "attribute".to_string(), - "wordsPosition".to_string(), - "exactness".to_string(), - "desc(downloads)".to_string(), - ]; let displayed_attributes = vec![ "mod_id".to_string(), @@ -311,7 +311,9 @@ pub async fn index_mods(conn: mongodb::Client) -> Result<(), Error>{ "icon_url".to_string(), "author_url".to_string(), "date_created".to_string(), + "created".to_string(), "date_modified".to_string(), + "updated".to_string(), "latest_version".to_string(), "empty".to_string(), ]; @@ -325,15 +327,76 @@ pub async fn index_mods(conn: mongodb::Client) -> Result<(), Error>{ "empty".to_string(), ]; - let write_settings = Settings::new() + let mut write_settings = Settings::new() .with_displayed_attributes(displayed_attributes) .with_searchable_attributes(searchable_attributes) - .with_accept_new_fields(settings.accept_new_fields.unwrap()) - .with_stop_words(settings.stop_words.unwrap()) - .with_synonyms(settings.synonyms.unwrap()) - .with_ranking_rules(ranking_rules); + .with_accept_new_fields(true) + .with_stop_words(vec![]) + .with_synonyms(HashMap::new()); - mods_index.set_settings(&write_settings).unwrap(); + //Relevance Index + let mut relevance_index = client.get_or_create("relevance_mods").unwrap(); + + let relevance_rules = vec![ + "typo".to_string(), + "words".to_string(), + "proximity".to_string(), + "attribute".to_string(), + "wordsPosition".to_string(), + "exactness".to_string(), + "desc(downloads)".to_string(), + ]; + + relevance_index.set_settings(&write_settings.with_ranking_rules(relevance_rules)).unwrap(); + relevance_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap(); + + //Downloads Index + let mut downloads_index = client.get_or_create("downloads_mods").unwrap(); + + let downloads_rules = vec![ + "desc(downloads)".to_string(), + "typo".to_string(), + "words".to_string(), + "proximity".to_string(), + "attribute".to_string(), + "wordsPosition".to_string(), + "exactness".to_string(), + ]; + + downloads_index.set_settings(&write_settings.with_ranking_rules(downloads_rules)).unwrap(); + downloads_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap(); + + //Updated Index + let mut updated_index = client.get_or_create("updated_mods").unwrap(); + + let updated_rules = vec![ + "desc(updated)".to_string(), + "typo".to_string(), + "words".to_string(), + "proximity".to_string(), + "attribute".to_string(), + "wordsPosition".to_string(), + "exactness".to_string(), + ]; + + updated_index.set_settings(&write_settings.with_ranking_rules(updated_rules)).unwrap(); + updated_index.add_documents(docs_to_add, Some("mod_id")).unwrap(); + + //Created Index + let mut newest_index = client.get_or_create("newest_mods").unwrap(); + + let newest_rules = vec![ + "desc(created)".to_string(), + "typo".to_string(), + "words".to_string(), + "proximity".to_string(), + "attribute".to_string(), + "wordsPosition".to_string(), + "exactness".to_string(), + ]; + + newest_index.set_settings(&write_settings.with_ranking_rules(newest_rules)).unwrap(); + newest_index.add_documents(docs_to_add.clone(), Some("mod_id")).unwrap(); Ok(()) } diff --git a/static/css/search.css b/static/css/search.css index e675b5e88..3e9e818ce 100644 --- a/static/css/search.css +++ b/static/css/search.css @@ -78,9 +78,10 @@ .filters select { height: 33px; width: 175px; + text-align: center; border-radius: 5px; - padding: 0 24px; + padding: 0 10px; background-color: #ffffff; background-image: none; border: 1px solid darkgrey; diff --git a/static/js/search.js b/static/js/search.js index b83cdef60..e2d48d46b 100644 --- a/static/js/search.js +++ b/static/js/search.js @@ -16,8 +16,8 @@ let category_inputs = { "forge": false, "fabric": false, } - let version_inputs = {}; +let selectedType = "relevance"; let resultContainer = document.getElementById("results"); @@ -144,6 +144,13 @@ function activateVersion(element) { handleSearch(0); } +function changeSortType(element) { + selectedType = element.options[element.selectedIndex].text; + console.log(selectedType) + + handleSearch(0); +} + let body = document.documentElement; let backToTop = document.getElementById("backToTop"); @@ -211,6 +218,10 @@ function handleSearch(index) { queryString += "&v=" + encodeURIComponent( "versions=" + versionString).replace(/%20/g,'+'); } + if(selectedType) { + queryString += "&s=" + encodeURIComponent(selectedType).replace(/%20/g,'+'); + } + if(index === 0) window.history.pushState('Search', 'Search', queryString); else diff --git a/templates/search.hbs b/templates/search.hbs index 5e6c4200d..8e39c3dec 100644 --- a/templates/search.hbs +++ b/templates/search.hbs @@ -33,11 +33,11 @@
- + + - +