You've already forked AstralRinth
forked from didirus/AstralRinth
Fixes missing plugin/datapack in search (#829)
* fixes datapack/plugin issue * fixes level * server side searching; org projects * total hits * total hits fixes --------- Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
@@ -6,22 +6,29 @@ use super::IndexingError;
|
||||
use crate::database::models::{project_item, version_item, ProjectId, VersionId};
|
||||
use crate::database::redis::RedisPool;
|
||||
use crate::models;
|
||||
use crate::models::v2::projects::LegacyProject;
|
||||
use crate::routes::v2_reroute;
|
||||
use crate::search::UploadSearchProject;
|
||||
use sqlx::postgres::PgPool;
|
||||
|
||||
pub async fn get_all_ids(
|
||||
pool: PgPool,
|
||||
) -> Result<Vec<(VersionId, ProjectId, String)>, IndexingError> {
|
||||
// TODO: Currently org owner is set to be considered owner. It may be worth considering
|
||||
// adding a new facetable 'organization' field to the search index, and using that instead,
|
||||
// and making owner to be optional.
|
||||
let all_visible_ids: Vec<(VersionId, ProjectId, String)> = sqlx::query!(
|
||||
"
|
||||
SELECT v.id id, m.id mod_id, u.username owner_username
|
||||
|
||||
SELECT v.id id, m.id mod_id, COALESCE(u.username, ou.username) owner_username
|
||||
FROM versions v
|
||||
INNER JOIN mods m ON v.mod_id = m.id AND m.status = ANY($2)
|
||||
INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.is_owner = TRUE AND tm.accepted = TRUE
|
||||
INNER JOIN users u ON tm.user_id = u.id
|
||||
LEFT JOIN team_members tm ON tm.team_id = m.team_id AND tm.is_owner = TRUE AND tm.accepted = TRUE
|
||||
LEFT JOIN users u ON tm.user_id = u.id
|
||||
LEFT JOIN organizations o ON o.id = m.organization_id
|
||||
LEFT JOIN team_members otm ON otm.team_id = o.team_id AND otm.is_owner = TRUE AND otm.accepted = TRUE
|
||||
LEFT JOIN users ou ON otm.user_id = ou.id
|
||||
WHERE v.status != ANY($1)
|
||||
GROUP BY v.id, m.id, u.id
|
||||
GROUP BY v.id, m.id, u.username, ou.username
|
||||
ORDER BY m.id DESC;
|
||||
",
|
||||
&*crate::models::projects::VersionStatus::iterator()
|
||||
@@ -38,7 +45,8 @@ pub async fn get_all_ids(
|
||||
Ok(e.right().map(|m| {
|
||||
let project_id: ProjectId = ProjectId(m.mod_id);
|
||||
let version_id: VersionId = VersionId(m.id);
|
||||
(version_id, project_id, m.owner_username)
|
||||
let owner_username = m.owner_username.unwrap_or_default();
|
||||
(version_id, project_id, owner_username)
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<_>>()
|
||||
@@ -114,7 +122,12 @@ pub async fn index_local(
|
||||
categories.append(&mut additional_categories);
|
||||
|
||||
let version_fields = v.version_fields.clone();
|
||||
let loader_fields = models::projects::from_duplicate_version_fields(version_fields);
|
||||
let unvectorized_loader_fields = v
|
||||
.version_fields
|
||||
.iter()
|
||||
.map(|vf| (vf.field_name.clone(), vf.value.serialize_internal()))
|
||||
.collect();
|
||||
let mut loader_fields = models::projects::from_duplicate_version_fields(version_fields);
|
||||
let license = match m.inner.license.split(' ').next() {
|
||||
Some(license) => license.to_string(),
|
||||
None => m.inner.license.clone(),
|
||||
@@ -158,6 +171,24 @@ pub async fn index_local(
|
||||
categories.retain(|x| *x != "mrpack");
|
||||
}
|
||||
|
||||
// SPECIAL BEHAVIOUR:
|
||||
// For consitency with v2 searching, we manually input the
|
||||
// client_side and server_side fields from the loader fields into
|
||||
// separate loader fields.
|
||||
// 'client_side' and 'server_side' remain supported by meilisearch even though they are no longer v3 fields.
|
||||
let (_, v2_og_project_type) = LegacyProject::get_project_type(&v.project_types);
|
||||
let (client_side, server_side) = v2_reroute::convert_side_types_v2(
|
||||
&unvectorized_loader_fields,
|
||||
Some(&v2_og_project_type),
|
||||
);
|
||||
|
||||
if let Ok(client_side) = serde_json::to_value(client_side) {
|
||||
loader_fields.insert("client_side".to_string(), vec![client_side]);
|
||||
}
|
||||
if let Ok(server_side) = serde_json::to_value(server_side) {
|
||||
loader_fields.insert("server_side".to_string(), vec![server_side]);
|
||||
}
|
||||
|
||||
let gallery = m
|
||||
.gallery_items
|
||||
.iter()
|
||||
|
||||
@@ -382,6 +382,9 @@ const DEFAULT_DISPLAYED_ATTRIBUTES: &[&str] = &[
|
||||
"singleplayer",
|
||||
"client_and_server",
|
||||
"mrpack_loaders",
|
||||
// V2 legacy fields for logical consistency
|
||||
"client_side",
|
||||
"server_side",
|
||||
// Non-searchable fields for filling out the Project model.
|
||||
"license_url",
|
||||
"monetization_status",
|
||||
@@ -424,6 +427,9 @@ const DEFAULT_ATTRIBUTES_FOR_FACETING: &[&str] = &[
|
||||
"singleplayer",
|
||||
"client_and_server",
|
||||
"mrpack_loaders",
|
||||
// V2 legacy fields for logical consistency
|
||||
"client_side",
|
||||
"server_side",
|
||||
];
|
||||
|
||||
const DEFAULT_SORTABLE_ATTRIBUTES: &[&str] =
|
||||
|
||||
@@ -142,8 +142,8 @@ pub struct UploadSearchProject {
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct SearchResults {
|
||||
pub hits: Vec<ResultSearchProject>,
|
||||
pub offset: usize,
|
||||
pub limit: usize,
|
||||
pub page: usize,
|
||||
pub hits_per_page: usize,
|
||||
pub total_hits: usize,
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ pub async fn search_for_project(
|
||||
) -> Result<SearchResults, SearchError> {
|
||||
let client = Client::new(&*config.address, Some(&*config.key));
|
||||
|
||||
let offset = info.offset.as_deref().unwrap_or("0").parse()?;
|
||||
let offset: usize = info.offset.as_deref().unwrap_or("0").parse()?;
|
||||
let index = info.index.as_deref().unwrap_or("relevance");
|
||||
let limit = info.limit.as_deref().unwrap_or("10").parse()?;
|
||||
|
||||
@@ -221,12 +221,15 @@ pub async fn search_for_project(
|
||||
|
||||
let mut filter_string = String::new();
|
||||
|
||||
// Convert offset and limit to page and hits_per_page
|
||||
let hits_per_page = limit;
|
||||
let page = offset / limit + 1;
|
||||
|
||||
let results = {
|
||||
let mut query = meilisearch_index.search();
|
||||
|
||||
query
|
||||
.with_limit(min(100, limit))
|
||||
.with_offset(offset)
|
||||
.with_page(page)
|
||||
.with_hits_per_page(hits_per_page)
|
||||
.with_query(info.query.as_deref().unwrap_or_default())
|
||||
.with_sort(&sort.1);
|
||||
|
||||
@@ -312,8 +315,8 @@ pub async fn search_for_project(
|
||||
|
||||
Ok(SearchResults {
|
||||
hits: results.hits.into_iter().map(|r| r.result).collect(),
|
||||
offset: results.offset.unwrap_or_default(),
|
||||
limit: results.limit.unwrap_or_default(),
|
||||
total_hits: results.estimated_total_hits.unwrap_or_default(),
|
||||
page: results.page.unwrap_or_default(),
|
||||
hits_per_page: results.hits_per_page.unwrap_or_default(),
|
||||
total_hits: results.total_hits.unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user