Skip to content
Snippets Groups Projects
Commit 576ecced authored by Richard Fernando Heise Ferreira's avatar Richard Fernando Heise Ferreira
Browse files

Merge branch 'elastic' into 'develop'

Issue #45: sortable filters

See merge request !67
parents 3d5fb199 3ef60160
No related branches found
No related tags found
1 merge request!67Issue #45: sortable filters
File deleted
...@@ -83,7 +83,7 @@ export class SearchRepo { ...@@ -83,7 +83,7 @@ export class SearchRepo {
created_at: sql`users.created_at`, created_at: sql`users.created_at`,
is_active: sql`users.is_active`, is_active: sql`users.is_active`,
score: sql`usst.score`, score: sql`usst.score`,
likes_received: sql`usst.likes_received`, likes: sql`usst.likes_received`,
followers: sql`usst.followers`, followers: sql`usst.followers`,
approved_resources: sql`usst.approved_resources`, approved_resources: sql`usst.approved_resources`,
}) })
...@@ -128,7 +128,7 @@ export class SearchRepo { ...@@ -128,7 +128,7 @@ export class SearchRepo {
downloads: sql`colst.downloads`, downloads: sql`colst.downloads`,
likes: sql`colst.likes`, likes: sql`colst.likes`,
shares: sql`colst.shares`, shares: sql`colst.shares`,
follows: sql`colst.follows`, followers: sql`colst.follows`,
}) })
.from(sql`collections col`) .from(sql`collections col`)
.leftJoin(sql`users`, sql`users.id = col.user_id`) .leftJoin(sql`users`, sql`users.id = col.user_id`)
......
import { z } from "zod"; import { z } from "zod";
import { resourceEnumSchema } from '../schema/resource-enum.schema'
export const resourceIndexSchema = z.object({ export const resourceIndexSchema = z.object({
id: z.number(), id: z.number(),
...@@ -13,7 +12,7 @@ export const resourceIndexSchema = z.object({ ...@@ -13,7 +12,7 @@ export const resourceIndexSchema = z.object({
subjects: z.string().nullable(), subjects: z.string().nullable(),
license: z.string(), license: z.string(),
object_type: z.string(), object_type: z.string(),
state: resourceEnumSchema, state: z.number(),
user: z.string(), user: z.string(),
views: z.number(), views: z.number(),
downloads: z.number(), downloads: z.number(),
...@@ -33,7 +32,7 @@ export const userIndexSchema = z.object({ ...@@ -33,7 +32,7 @@ export const userIndexSchema = z.object({
created_at: z.string(), created_at: z.string(),
is_active: z.boolean(), is_active: z.boolean(),
score: z.number(), score: z.number(),
likes_received: z.number(), likes: z.number(),
followers: z.number(), followers: z.number(),
approved_resources: z.number() approved_resources: z.number()
}); });
...@@ -49,7 +48,7 @@ export const collectionIndexSchema = z.object({ ...@@ -49,7 +48,7 @@ export const collectionIndexSchema = z.object({
downloads: z.number(), downloads: z.number(),
likes: z.number(), likes: z.number(),
shares: z.number(), shares: z.number(),
follows: z.number() followers: z.number()
}); });
// export type LearningObjectIndex = z.infer<typeof learningObjectIndexSchema>; // export type LearningObjectIndex = z.infer<typeof learningObjectIndexSchema>;
......
...@@ -21,7 +21,7 @@ export const searchRouter = new Hono() ...@@ -21,7 +21,7 @@ export const searchRouter = new Hono()
try { try {
const { query } = c.req.valid('query'); const { query } = c.req.valid('query');
const results = await searchService.searchIndex(query, {}); const results = await searchService.searchIndex(query);
return c.json({ results }); return c.json({ results });
} catch (e) { } catch (e) {
......
...@@ -219,6 +219,8 @@ export const userRouter = honoWithJwt() ...@@ -219,6 +219,8 @@ export const userRouter = honoWithJwt()
await service.update(input) await service.update(input)
) )
await searchService.indexUser(user.id)
return c.json({ user }) return c.json({ user })
} catch (e) { } catch (e) {
......
...@@ -3,12 +3,25 @@ import es from '@/search' ...@@ -3,12 +3,25 @@ import es from '@/search'
import env from '@/env' import env from '@/env'
import { SearchRepo } from "@/db/repo/search.repo"; import { SearchRepo } from "@/db/repo/search.repo";
type ExactFilterFields = { export type ExactFilterFields = {
language?: string; language?: string;
objectType?: string; objectType?: string;
institution?: string; institution?: string;
state?: number;
}; };
export type SortableFilterFields = {
created_at?: string;
views?: number;
downloads?: number;
likes?: number;
shares?: number;
score?: number;
comments?: number;
followers?: number;
approved_resources?: number;
}
@Service() @Service()
export class SearchService { export class SearchService {
@Inject('ElasticSearchClient') @Inject('ElasticSearchClient')
...@@ -81,7 +94,7 @@ export class SearchService { ...@@ -81,7 +94,7 @@ export class SearchService {
downloads: document.downloads, downloads: document.downloads,
likes: document.likes, likes: document.likes,
shares: document.shares, shares: document.shares,
follows: document.follows followers: document.followers,
}, },
}); });
...@@ -113,7 +126,7 @@ export class SearchService { ...@@ -113,7 +126,7 @@ export class SearchService {
created_at: document.created_at, created_at: document.created_at,
is_active: document.is_active, is_active: document.is_active,
score: document.score, score: document.score,
likes_received: document.likes_received, likes: document.likes,
followers: document.followers, followers: document.followers,
approved_resources: document.approved_resources approved_resources: document.approved_resources
}, },
...@@ -133,25 +146,31 @@ export class SearchService { ...@@ -133,25 +146,31 @@ export class SearchService {
// page_size: tamanho da página // page_size: tamanho da página
async searchIndex( async searchIndex(
query: string, query: string,
filters: Partial<ExactFilterFields>, filters: Partial<ExactFilterFields> = {},
sortBy?: 'created_at', sortBy: Partial<SortableFilterFields> = {},
// sortBy?: 'created_at',
sortOrder: 'asc' | 'desc' = 'desc', sortOrder: 'asc' | 'desc' = 'desc',
index: string[] = [env.ELASTIC_INDEX_USERS, env.ELASTIC_INDEX_COLLECTIONS, env.ELASTIC_INDEX_RESOURCES], index: string[] = [env.ELASTIC_INDEX_USERS, env.ELASTIC_INDEX_COLLECTIONS, env.ELASTIC_INDEX_RESOURCES],
offset: number = 0, offset: number = 0,
page_size: number = 1000 page_size: number = 1000
) { ) {
const filterClauses = Object.entries(filters) const userFilters = Object.entries(filters)
.filter(([, value]) => value !== undefined) .filter(([, value]) => value !== undefined)
.map(([key, value]) => ({ .map(([key, value]) => {
term: { [key]: value }, if (Array.isArray(value)) {
})); return { terms: { [key]: value } };
} else {
return { term: { [key]: value } };
}
});
let sort: Array<{ [key: string]: { order: 'asc' | 'desc' } }> = []; let sort: Array<{ [key: string]: { order: 'asc' | 'desc' } }> = [];
if (sortBy) { if (sortBy && Object.keys(sortBy).length > 0) {
const sortField = Object.keys(sortBy)[0];
sort = [ sort = [
{ {
[sortBy]: { [sortField]: {
order: sortOrder, order: sortOrder,
}, },
}, },
...@@ -174,7 +193,6 @@ export class SearchService { ...@@ -174,7 +193,6 @@ export class SearchService {
'author', 'author',
'description', 'description',
'link', 'link',
'fileFormats',
'educational_stages', 'educational_stages',
'languages', 'languages',
'subjects', 'subjects',
...@@ -185,9 +203,9 @@ export class SearchService { ...@@ -185,9 +203,9 @@ export class SearchService {
'roles', 'roles',
'institution', 'institution',
'city', 'city',
'views', // 'views',
'downloads', // 'downloads',
'likes', // 'likes',
'shares', 'shares',
'score', 'score',
'comments', 'comments',
...@@ -195,7 +213,7 @@ export class SearchService { ...@@ -195,7 +213,7 @@ export class SearchService {
}, },
}, },
], ],
filter: filterClauses, filter: userFilters,
}, },
}, },
sort: sort.length > 0 ? sort : undefined, sort: sort.length > 0 ? sort : undefined,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment