Skip to content

Commit

Permalink
Handle the case when total.relation is gte
Browse files Browse the repository at this point in the history
Els 7 から totalCount が max window 以上を返さなくなったのに対応

Close #6
  • Loading branch information
nonylene committed Feb 8, 2024
1 parent fac8179 commit d7fd167
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 36 deletions.
12 changes: 2 additions & 10 deletions app/components/status-indicator/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { faChartSimple } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ELASTIC_SEARCH_MAX_SEARCH_WINDOW } from "~/utils";

interface StatusIndicatorProps {
currentPage: number;
Expand All @@ -17,20 +16,13 @@ export function StatusIndicator(props: StatusIndicatorProps) {
} else {
const page = props.currentPage;
const pageStr = page > 1 ? `Page ${page} of ` : "";
text = `${pageStr}${props.totalCount!} hits`;
text = `${pageStr}${props.totalCount!}${props.overMaxWindow ? "+" : ""} hits`;
}
return (
<div className="col-7 offset-md-1 StatusIndicator">
<p>
<FontAwesomeIcon icon={faChartSimple} />
&ensp;{text}&ensp;
<span
className={
"small d-none" + (props.overMaxWindow ? " d-sm-inline-block" : "")
}
>
{ELASTIC_SEARCH_MAX_SEARCH_WINDOW + 1}件目以上は表示されません)
</span>
&ensp;{text}
</p>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions app/routes/help/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ export default function Help() {
`Index の都合により 1 文字では検索できません。
<a href="${pukiwikiBaseURL}?cmd=search">PukiWiki の検索機能</a>
を使って下さい。`,
`Elasticsearch の仕様で 10000 件を超える検索結果は出力されません。`,
`<code>C#</code> や <code>C++</code> といった記号でも検索可能です。`,
`更新されたばかりのページはクロールされるまで検索に出ません。`,
]}
Expand Down
2 changes: 2 additions & 0 deletions app/routes/search.mail/els-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function createMessageResultFromResponse(json: any): MessageResult {
createMessageFromResponse(item),
),
totalCount: json.hits.total.value,
overMaxWindow: json.hits.total.relation === "gte",
};
}

Expand Down Expand Up @@ -144,6 +145,7 @@ export async function requestSearch({

const response = await fetch(url);
if (!response.ok) {
console.error(await response.json());
throw new Response(
`Invalid response from the backend elasticsearch server: ${response.statusText}`,
{ status: 500 },
Expand Down
1 change: 1 addition & 0 deletions app/routes/search.mail/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export interface Message {
export interface MessageResult {
messages: Message[];
totalCount: number;
overMaxWindow: boolean;
}
15 changes: 7 additions & 8 deletions app/routes/search.mail/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import HeinekenError from "~/components/heineken-error";
import { Pager, links as pagerLinks } from "~/components/pager";
import SortButton from "~/components/sort-button";
import { StatusIndicator } from "~/components/status-indicator";
import { ELASTIC_SEARCH_MAX_SEARCH_WINDOW } from "~/utils";
import { calculateTotalPages } from "~/utils";

const sortOrderOptions = [
{ value: "s", label: "Score" },
Expand Down Expand Up @@ -153,17 +153,16 @@ export default function Mail() {
};

const render = (messageResult: MessageResult) => {
// We cannot search over the window limit of elasticsearch.
const totalPages = Math.min(
Math.ceil(messageResult.totalCount / SEARCH_SIZE),
Math.floor(ELASTIC_SEARCH_MAX_SEARCH_WINDOW / SEARCH_SIZE),
);
return (
<div className="mt-3">
<MessageList messageResult={messageResult} mailBaseURL={mailBaseURL} />
<Pager
currentPage={page}
totalPages={totalPages}
totalPages={calculateTotalPages(
SEARCH_SIZE,
messageResult.totalCount,
messageResult.overMaxWindow,
)}
onNewPage={onNewPage}
/>
</div>
Expand All @@ -181,7 +180,7 @@ export default function Mail() {
currentPage={page}
totalCount={mr.totalCount}
requesting={requesting}
overMaxWindow={ELASTIC_SEARCH_MAX_SEARCH_WINDOW < mr.totalCount}
overMaxWindow={mr.overMaxWindow}
/>
)}
</Await>
Expand Down
2 changes: 2 additions & 0 deletions app/routes/search.pukiwiki/els-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function createPageResultFromResponse(json: any): PageResult {
return {
pages: json.hits.hits.map((item: unknown) => createPageFromResponse(item)),
totalCount: json.hits.total.value,
overMaxWindow: json.hits.total.relation === "gte",
};
}

Expand Down Expand Up @@ -138,6 +139,7 @@ export async function requestSearch({

const response = await fetch(url);
if (!response.ok) {
console.error(await response.json());
throw new Response(
`Invalid response from the backend elasticsearch server: ${response.statusText}`,
{ status: 500 },
Expand Down
1 change: 1 addition & 0 deletions app/routes/search.pukiwiki/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export interface Page {
export interface PageResult {
pages: Page[];
totalCount: number;
overMaxWindow: boolean;
}
15 changes: 7 additions & 8 deletions app/routes/search.pukiwiki/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import HeinekenError from "~/components/heineken-error";
import { Pager, links as pagerLinks } from "~/components/pager";
import SortButton from "~/components/sort-button";
import { StatusIndicator } from "~/components/status-indicator";
import { ELASTIC_SEARCH_MAX_SEARCH_WINDOW } from "~/utils";
import { calculateTotalPages } from "~/utils";

const sortOrderOptions = [
{ value: "s", label: "Score" },
Expand Down Expand Up @@ -143,17 +143,16 @@ export default function PukiWiki() {
};

const render = (pageResult: PageResult) => {
// We cannot search over the window limit of elasticsearch.
const totalPages = Math.min(
Math.ceil(pageResult.totalCount / SEARCH_SIZE),
Math.floor(ELASTIC_SEARCH_MAX_SEARCH_WINDOW / SEARCH_SIZE),
);
return (
<div className="mt-3">
<PageList pageResult={pageResult} pukiwikiBaseURL={pukiwikiBaseURL} />
<Pager
currentPage={page}
totalPages={totalPages}
totalPages={calculateTotalPages(
SEARCH_SIZE,
pageResult.totalCount,
pageResult.overMaxWindow,
)}
onNewPage={onNewPage}
/>
</div>
Expand All @@ -171,7 +170,7 @@ export default function PukiWiki() {
currentPage={page}
totalCount={pr.totalCount}
requesting={requesting}
overMaxWindow={ELASTIC_SEARCH_MAX_SEARCH_WINDOW < pr.totalCount}
overMaxWindow={pr.overMaxWindow}
/>
)}
</Await>
Expand Down
2 changes: 2 additions & 0 deletions app/routes/search.scrapbox/els-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function createPageResultFromResponse(json: any): PageResult {
return {
pages: json.hits.hits.map((item: unknown) => createPageFromResponse(item)),
totalCount: json.hits.total.value,
overMaxWindow: json.hits.total.relation === "gte",
};
}

Expand Down Expand Up @@ -128,6 +129,7 @@ export async function requestSearch({

const response = await fetch(url);
if (!response.ok) {
console.error(await response.json());
throw new Response(
`Invalid response from the backend elasticsearch server: ${response.statusText}`,
{ status: 500 },
Expand Down
1 change: 1 addition & 0 deletions app/routes/search.scrapbox/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export interface Page {
export interface PageResult {
pages: Page[];
totalCount: number;
overMaxWindow: boolean;
}
15 changes: 7 additions & 8 deletions app/routes/search.scrapbox/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import HeinekenError from "~/components/heineken-error";
import { Pager, links as pagerLinks } from "~/components/pager";
import SortButton from "~/components/sort-button";
import { StatusIndicator } from "~/components/status-indicator";
import { ELASTIC_SEARCH_MAX_SEARCH_WINDOW } from "~/utils";
import { calculateTotalPages } from "~/utils";

const sortOrderOptions = [
{ value: "s", label: "Score" },
Expand Down Expand Up @@ -143,17 +143,16 @@ export default function ScrapBox() {
};

const render = (pageResult: PageResult) => {
// We cannot search over the window limit of elasticsearch.
const totalPages = Math.min(
Math.ceil(pageResult.totalCount / SEARCH_SIZE),
Math.floor(ELASTIC_SEARCH_MAX_SEARCH_WINDOW / SEARCH_SIZE),
);
return (
<div className="mt-3">
<PageList pageResult={pageResult} scrapboxBaseURL={scrapboxBaseURL} />
<Pager
currentPage={page}
totalPages={totalPages}
totalPages={calculateTotalPages(
SEARCH_SIZE,
pageResult.totalCount,
pageResult.overMaxWindow,
)}
onNewPage={onNewPage}
/>
</div>
Expand All @@ -171,7 +170,7 @@ export default function ScrapBox() {
currentPage={page}
totalCount={pr.totalCount}
requesting={requesting}
overMaxWindow={ELASTIC_SEARCH_MAX_SEARCH_WINDOW < pr.totalCount}
overMaxWindow={pr.overMaxWindow}
/>
)}
</Await>
Expand Down
11 changes: 9 additions & 2 deletions app/utils/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ export function truncate(text: string, max: number) {
else return text;
}

export const ELASTIC_SEARCH_MAX_SEARCH_WINDOW = 10000;

const ELASTIC_QUERY_STRING_ESACPE_CHARS = ['"', "\\"];

// Baisis: Split by space and call them as words. Words are joined with AND and quoted
Expand Down Expand Up @@ -171,3 +169,12 @@ export function toQueryString(query: string) {
})
.join(" AND ");
}

export const calculateTotalPages = (
searchSize: number,
totalCount: number,
overMaxWindow: boolean,
) => {
// overMaxWindow のときは最後のページが max window 以上の結果を指してしまいエラーになる
return (overMaxWindow ? Math.floor : Math.ceil)(totalCount / searchSize);
};

0 comments on commit d7fd167

Please sign in to comment.