Fix Typesense tests (#5541)

* Fix Typesense tests

* fix

* add back author

* Split project title and authors by words and index on that

* clippy
This commit is contained in:
aecsocket
2026-03-13 13:34:51 +00:00
committed by GitHub
parent cc9059fb4a
commit 991b4d8c13
8 changed files with 66 additions and 8 deletions

View File

@@ -208,7 +208,7 @@ pub async fn profile_check_installed_batch(
projects.into_iter().any(|(_, pf)| {
pf.metadata
.as_ref()
.map_or(false, |m| m.project_id == project_id)
.is_some_and(|m| m.project_id == project_id)
})
} else {
false

View File

@@ -48,6 +48,7 @@ elasticsearch = { workspace = true, features = ["experimental-apis"] }
eyre = { workspace = true }
futures = { workspace = true }
futures-util = { workspace = true }
heck = { workspace = true }
hex = { workspace = true }
hmac = { workspace = true }
hyper-rustls = { workspace = true }

View File

@@ -136,6 +136,21 @@ impl SearchField {
path: "categories",
mapping: json!({ "type": "keyword" }),
},
SearchField::Name => ElasticsearchFieldSpec {
path: "name",
mapping: json!({ "type": "search_as_you_type" }),
},
SearchField::Author => ElasticsearchFieldSpec {
path: "author",
mapping: json!({
"type": "search_as_you_type",
"fields": { "keyword": { "type": "keyword" } }
}),
},
SearchField::License => ElasticsearchFieldSpec {
path: "license",
mapping: json!({ "type": "keyword" }),
},
SearchField::ProjectTypes => ElasticsearchFieldSpec {
path: "project_types",
mapping: json!({ "type": "keyword" }),

View File

@@ -557,6 +557,18 @@ impl SearchField {
path: "categories",
filterable: true,
},
SearchField::Name => MeilisearchFieldSpec {
path: "name",
filterable: true,
},
SearchField::Author => MeilisearchFieldSpec {
path: "author",
filterable: true,
},
SearchField::License => MeilisearchFieldSpec {
path: "license",
filterable: true,
},
SearchField::ProjectTypes => MeilisearchFieldSpec {
path: "project_types",
filterable: true,

View File

@@ -105,18 +105,18 @@ impl Default for RequestConfig {
}
fn default_query_by() -> Vec<String> {
["name", "slug", "summary"]
["indexed_title", "slug", "summary", "indexed_author"]
.into_iter()
.map(str::to_string)
.collect()
}
fn default_query_by_weights() -> Vec<u8> {
vec![15, 5, 2]
vec![15, 5, 2, 1]
}
fn default_prefix() -> Vec<bool> {
vec![true, true, false]
vec![true, true, true, true]
}
const fn default_prioritize_exact_match() -> bool {
@@ -346,6 +346,27 @@ impl SearchField {
sort: false,
optional: true,
},
SearchField::Name => TypesenseFieldSpec {
path: "name",
ty: "string",
facet: true,
sort: false,
optional: false,
},
SearchField::Author => TypesenseFieldSpec {
path: "author",
ty: "string",
facet: true,
sort: false,
optional: false,
},
SearchField::License => TypesenseFieldSpec {
path: "license",
ty: "string",
facet: true,
sort: false,
optional: true,
},
SearchField::ProjectTypes => TypesenseFieldSpec {
path: "project_types",
ty: "string[]",
@@ -468,12 +489,11 @@ impl Typesense {
fn collection_schema(name: &str) -> Value {
let mut fields = vec![
json!({"name": "name", "type": "string", "facet": false}),
json!({"name": "summary", "type": "string", "facet": false}),
json!({"name": "slug", "type": "string", "facet": false}),
json!({"name": "indexed_title", "type": "string", "facet": false}),
json!({"name": "indexed_author", "type": "string", "facet": false}),
json!({"name": "log_downloads", "type": "float", "sort": true}),
json!({"name": "author", "type": "string", "facet": true}),
json!({"name": "license", "type": "string", "facet": true}),
json!({"name": "follows", "type": "int32", "facet": true, "sort": true}),
json!({"name": "created_timestamp", "type": "int64", "sort": true}),
json!({"name": "modified_timestamp", "type": "int64", "sort": true}),
@@ -487,6 +507,7 @@ impl Typesense {
json!({
"name": name,
"enable_nested_fields": true,
"token_separators": ["-"],
"fields": fields,
"default_sorting_field": "log_downloads"
})
@@ -596,7 +617,7 @@ impl Typesense {
};
let new_filters_part =
info.new_filters.as_deref().map(|f| meili_to_typesense(f));
info.new_filters.as_deref().map(meili_to_typesense);
let legacy_part = if info.new_filters.is_none() {
combined_search_filters(info).map(|f| meili_to_typesense(&f))

View File

@@ -2,6 +2,7 @@ use chrono::{DateTime, Utc};
use dashmap::DashMap;
use eyre::Result;
use futures::TryStreamExt;
use heck::ToKebabCase;
use itertools::Itertools;
use std::collections::HashMap;
use tracing::info;
@@ -426,6 +427,7 @@ pub async fn index_local(
project_id: crate::models::ids::ProjectId::from(project.id)
.to_string(),
name: project.name.clone(),
indexed_title: project.name.to_kebab_case(),
summary: project.summary.clone(),
categories: categories.clone(),
display_categories: display_categories.clone(),
@@ -434,6 +436,7 @@ pub async fn index_local(
log_downloads: (project.downloads.max(1) as f64).ln(),
icon_url: project.icon_url.clone(),
author: owner.clone(),
indexed_author: owner.to_kebab_case(),
date_created: project.approved,
created_timestamp: project.approved.timestamp(),
date_modified: project.updated,

View File

@@ -186,6 +186,9 @@ pub enum SearchBackendKind {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter)]
pub enum SearchField {
Categories,
Name,
Author,
License,
ProjectTypes,
ProjectId,
OpenSource,
@@ -225,7 +228,9 @@ pub struct UploadSearchProject {
pub project_types: Vec<String>,
pub slug: Option<String>,
pub author: String,
pub indexed_author: String,
pub name: String,
pub indexed_title: String,
pub summary: String,
pub categories: Vec<String>,
pub display_categories: Vec<String>,