fix: add column to posts table that is a string of content to use search index on
This commit is contained in:
+21
-6
@@ -28,8 +28,10 @@ export const createOrUpdatePost = mutation({
|
|||||||
return 'CANNOT_POST_ON_BEHALF_OF_ANOTHER_USER';
|
return 'CANNOT_POST_ON_BEHALF_OF_ANOTHER_USER';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contentText = args.content.join('\n');
|
||||||
|
|
||||||
if (args.id) {
|
if (args.id) {
|
||||||
await ctx.db.patch(args.id, { content: args.content });
|
await ctx.db.patch(args.id, { content: args.content, contentText });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +39,7 @@ export const createOrUpdatePost = mutation({
|
|||||||
userId: user._id,
|
userId: user._id,
|
||||||
content: args.content,
|
content: args.content,
|
||||||
parentPostId: args.parentPostId,
|
parentPostId: args.parentPostId,
|
||||||
|
contentText,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -44,12 +47,16 @@ export const createOrUpdatePost = mutation({
|
|||||||
export const getUsersPostById = query({
|
export const getUsersPostById = query({
|
||||||
args: { userId: v.id('users'), paginationOpts: paginationOptsValidator },
|
args: { userId: v.id('users'), paginationOpts: paginationOptsValidator },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
return await ctx.db
|
const posts = await ctx.db
|
||||||
.query('posts')
|
.query('posts')
|
||||||
.withIndex('by_user_id', q => q.eq('userId', args.userId))
|
.withIndex('by_user_id', q => q.eq('userId', args.userId))
|
||||||
.filter(q => q.eq(q.field('parentPostId'), undefined))
|
.filter(q => q.eq(q.field('parentPostId'), undefined))
|
||||||
.order('desc')
|
.order('desc')
|
||||||
.paginate(args.paginationOpts);
|
.paginate(args.paginationOpts);
|
||||||
|
|
||||||
|
const postDtos = posts.page.map(createPostDto);
|
||||||
|
|
||||||
|
return { ...posts, page: postDtos };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -81,7 +88,7 @@ export const getPostById = query({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...post,
|
...createPostDto(post),
|
||||||
user: createUserDto(user),
|
user: createUserDto(user),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -100,6 +107,7 @@ export const getRepliesByParentId = query({
|
|||||||
ctx,
|
ctx,
|
||||||
posts: replies.page,
|
posts: replies.page,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { ...replies, page: repliesWithUserData };
|
return { ...replies, page: repliesWithUserData };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -191,8 +199,9 @@ export const getPostsBySearchTerm = query({
|
|||||||
const posts = await ctx.db
|
const posts = await ctx.db
|
||||||
.query('posts')
|
.query('posts')
|
||||||
.withSearchIndex('search_by_content', q =>
|
.withSearchIndex('search_by_content', q =>
|
||||||
q.search('content', args.term).eq('parentPostId', undefined)
|
q.search('contentText', args.term)
|
||||||
)
|
)
|
||||||
|
.filter(q => q.eq(q.field('parentPostId'), undefined))
|
||||||
.paginate(args.paginationOpts);
|
.paginate(args.paginationOpts);
|
||||||
|
|
||||||
const postsWithUser = await getPostsWithUsers({ ctx, posts: posts.page });
|
const postsWithUser = await getPostsWithUsers({ ctx, posts: posts.page });
|
||||||
@@ -210,19 +219,25 @@ async function getPostsWithUsers({
|
|||||||
}) {
|
}) {
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
posts.map(async post => {
|
posts.map(async post => {
|
||||||
|
const postDto = createPostDto(post);
|
||||||
const user = await ctx.db.get(post.userId);
|
const user = await ctx.db.get(post.userId);
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
return {
|
return {
|
||||||
...post,
|
...postDto,
|
||||||
user: createUserDto(user),
|
user: createUserDto(user),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...post,
|
...postDto,
|
||||||
user: createUserDto(user),
|
user: createUserDto(user),
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createPostDto(post: Doc<'posts'>) {
|
||||||
|
const { contentText, ...postDto } = post;
|
||||||
|
return postDto;
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -44,11 +44,12 @@ export default defineSchema(
|
|||||||
parentPostId: v.optional(v.id('posts')),
|
parentPostId: v.optional(v.id('posts')),
|
||||||
userId: v.id('users'),
|
userId: v.id('users'),
|
||||||
content: v.array(v.string()),
|
content: v.array(v.string()),
|
||||||
|
contentText: v.string(),
|
||||||
})
|
})
|
||||||
.index('by_user_id', ['userId'])
|
.index('by_user_id', ['userId'])
|
||||||
.index('by_parent_id', ['parentPostId'])
|
.index('by_parent_id', ['parentPostId'])
|
||||||
.searchIndex('search_by_content', {
|
.searchIndex('search_by_content', {
|
||||||
searchField: 'content',
|
searchField: 'contentText',
|
||||||
filterFields: ['parentPostId'],
|
filterFields: ['parentPostId'],
|
||||||
}),
|
}),
|
||||||
likes: defineTable({
|
likes: defineTable({
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import SearchResults from '@/components/SearchResults';
|
|
||||||
|
|
||||||
export default function SearchPage({ params }: { params: { term: string } }) {
|
|
||||||
return (
|
|
||||||
<main className='flex flex-col items-center flex-1'>
|
|
||||||
<div className='flex flex-col w-full max-w-4xl gap-4'>
|
|
||||||
<h1 className='text-4xl font-bold'>Here's what we found</h1>
|
|
||||||
<SearchResults term={params.term} />
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import SearchResults from '@/components/SearchResults';
|
||||||
|
|
||||||
|
export default function SearchPage({
|
||||||
|
searchParams,
|
||||||
|
}: {
|
||||||
|
searchParams: { [key: string]: string | string[] | undefined };
|
||||||
|
}) {
|
||||||
|
let term = searchParams.term;
|
||||||
|
|
||||||
|
if (term === undefined) {
|
||||||
|
term = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(term)) {
|
||||||
|
term = term.length > 0 ? term[0] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className='flex flex-col items-center flex-1'>
|
||||||
|
<div className='flex flex-col w-full max-w-4xl gap-4'>
|
||||||
|
<h1 className='text-4xl font-bold'>Here's what we found</h1>
|
||||||
|
<SearchResults term={term} />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,4 +8,6 @@ export type UserDto = {
|
|||||||
clerkUserId: string;
|
clerkUserId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PostWithUserDto = Doc<'posts'> & { user: UserDto };
|
export type PostWithUserDto = Omit<Doc<'posts'>, 'contentText'> & {
|
||||||
|
user: UserDto;
|
||||||
|
};
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default function Navbar() {
|
|||||||
<form
|
<form
|
||||||
onSubmit={e => {
|
onSubmit={e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
router.push(`/search/${term}`);
|
router.push(`/search?term=${term}`);
|
||||||
}}
|
}}
|
||||||
className='flex w-full relative'
|
className='flex w-full relative'
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user