feat: add search filter "from: me"
This commit is contained in:
parent
c7cfd66650
commit
7e23a6d32d
3 changed files with 58 additions and 42 deletions
|
@ -10,9 +10,13 @@
|
|||
|
||||
## 主要な変更点
|
||||
|
||||
- 検索フィルターを強化中
|
||||
- `from: me` を検索ワードの末尾につけると自分の投稿のみを検索できるように変更
|
||||
- 検索クエリの例: `予定 from:me`
|
||||
- ホーム・フォロワー限定・ダイレクト・秘密の投稿を含む自分の全ての投稿から検索します
|
||||
- 全文検索のエンジンを [PGroonga](https://pgroonga.github.io/) に変更
|
||||
- PGroonga のインストールが必要になります!詳しくは[この投稿](https://post.naskya.net/notes/9ldi29amfanomef5)をご覧ください
|
||||
- Meilisearch, Elasticsearch, Sonic は非推奨となります
|
||||
- Meilisearch, Elasticsearch, Sonic は使えません
|
||||
- 「秘密」という公開範囲を追加
|
||||
- 宛先無しのダイレクト投稿を言い換えているだけです
|
||||
- 既存の投稿を削除せずに後から秘密にすることもできます
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { FindManyOptions, In } from "typeorm";
|
||||
// import { FindManyOptions, In } from "typeorm";
|
||||
import { Notes } from "@/models/index.js";
|
||||
import { Note } from "@/models/entities/note.js";
|
||||
import config from "@/config/index.js";
|
||||
import es from "@/db/elasticsearch.js";
|
||||
import sonic from "@/db/sonic.js";
|
||||
import meilisearch, { MeilisearchNote } from "@/db/meilisearch.js";
|
||||
// import config from "@/config/index.js";
|
||||
// import es from "@/db/elasticsearch.js";
|
||||
// import sonic from "@/db/sonic.js";
|
||||
// import meilisearch, { MeilisearchNote } from "@/db/meilisearch.js";
|
||||
import define from "@/server/api/define.js";
|
||||
import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js";
|
||||
import { generateVisibilityQuery } from "@/server/api/common/generate-visibility-query.js";
|
||||
|
@ -73,47 +73,55 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
// disable the post search if no credentials are provided
|
||||
if (me == null) return [];
|
||||
|
||||
if (es == null && sonic == null && meilisearch == null) {
|
||||
const query = makePaginationQuery(
|
||||
Notes.createQueryBuilder("note"),
|
||||
ps.sinceId,
|
||||
ps.untilId,
|
||||
);
|
||||
/* if (es == null && sonic == null && meilisearch == null) { */
|
||||
const query = makePaginationQuery(
|
||||
Notes.createQueryBuilder("note"),
|
||||
ps.sinceId,
|
||||
ps.untilId,
|
||||
);
|
||||
|
||||
if (ps.userId != null) {
|
||||
query.andWhere("note.userId = :userId", { userId: ps.userId });
|
||||
}
|
||||
if (ps.channelId != null) {
|
||||
query.andWhere("note.channelId = :channelId", {
|
||||
channelId: ps.channelId,
|
||||
});
|
||||
}
|
||||
|
||||
if (ps.channelId != null) {
|
||||
query.andWhere("note.channelId = :channelId", {
|
||||
channelId: ps.channelId,
|
||||
});
|
||||
}
|
||||
query
|
||||
.andWhere("note.text &@~ :q", { q: `${sqlLikeEscape(ps.query)}` })
|
||||
.innerJoinAndSelect("note.user", "user");
|
||||
|
||||
// "from: me": search all (public, home, followers, specified) my posts
|
||||
// otherwise: search public indexable posts only
|
||||
if (ps.userId == null || ps.userId !== me.id) {
|
||||
query
|
||||
.andWhere("note.text &@~ :q", { q: `${sqlLikeEscape(ps.query)}` })
|
||||
.andWhere("note.visibility = 'public'")
|
||||
.innerJoinAndSelect("note.user", "user")
|
||||
.andWhere("user.isIndexable = TRUE")
|
||||
.leftJoinAndSelect("user.avatar", "avatar")
|
||||
.leftJoinAndSelect("user.banner", "banner")
|
||||
.leftJoinAndSelect("note.reply", "reply")
|
||||
.leftJoinAndSelect("note.renote", "renote")
|
||||
.leftJoinAndSelect("reply.user", "replyUser")
|
||||
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
|
||||
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
|
||||
.leftJoinAndSelect("renote.user", "renoteUser")
|
||||
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
|
||||
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
|
||||
.andWhere("user.isIndexable = TRUE");
|
||||
}
|
||||
|
||||
generateVisibilityQuery(query, me);
|
||||
if (me) generateMutedUserQuery(query, me);
|
||||
if (me) generateBlockedUserQuery(query, me);
|
||||
if (ps.userId != null) {
|
||||
query.andWhere("note.userId = :userId", { userId: ps.userId });
|
||||
}
|
||||
|
||||
const notes: Note[] = await query.take(ps.limit).getMany();
|
||||
query
|
||||
.leftJoinAndSelect("user.avatar", "avatar")
|
||||
.leftJoinAndSelect("user.banner", "banner")
|
||||
.leftJoinAndSelect("note.reply", "reply")
|
||||
.leftJoinAndSelect("note.renote", "renote")
|
||||
.leftJoinAndSelect("reply.user", "replyUser")
|
||||
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
|
||||
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
|
||||
.leftJoinAndSelect("renote.user", "renoteUser")
|
||||
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
|
||||
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
|
||||
|
||||
return await Notes.packMany(notes, me);
|
||||
} else if (sonic) {
|
||||
generateVisibilityQuery(query, me);
|
||||
if (me) generateMutedUserQuery(query, me);
|
||||
if (me) generateBlockedUserQuery(query, me);
|
||||
|
||||
const notes: Note[] = await query.take(ps.limit).getMany();
|
||||
|
||||
return await Notes.packMany(notes, me);
|
||||
/* } else if (sonic) {
|
||||
let start = 0;
|
||||
const chunkSize = 100;
|
||||
|
||||
|
@ -270,7 +278,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
}
|
||||
|
||||
return found;
|
||||
} else {
|
||||
} else { // Elasticsearch
|
||||
const userQuery =
|
||||
ps.userId != null
|
||||
? [
|
||||
|
@ -350,5 +358,5 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
});
|
||||
|
||||
return await Notes.packMany(notes, me);
|
||||
}
|
||||
} */
|
||||
});
|
||||
|
|
|
@ -50,6 +50,7 @@ import { definePageMetadata } from "@/scripts/page-metadata";
|
|||
import { defaultStore } from "@/store";
|
||||
import { deviceKind } from "@/scripts/device-kind";
|
||||
import icon from "@/scripts/icon";
|
||||
import { $i } from "@/reactiveAccount";
|
||||
import "swiper/scss";
|
||||
import "swiper/scss/virtual";
|
||||
|
||||
|
@ -62,7 +63,10 @@ const notesPagination = {
|
|||
endpoint: "notes/search" as const,
|
||||
limit: 10,
|
||||
params: computed(() => ({
|
||||
query: props.query,
|
||||
query: props.query.endsWith("from:me")
|
||||
? props.query.slice(0, -7).trim()
|
||||
: props.query,
|
||||
userId: props.query.endsWith("from:me") ? $i.id : null,
|
||||
channelId: props.channel,
|
||||
})),
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue