metaforecast/src/graphql/schema/search.ts

71 lines
2.3 KiB
TypeScript

import { guesstimate } from "../../backend/platforms/guesstimate";
import { AlgoliaQuestion } from "../../backend/utils/algolia";
import searchWithAlgolia from "../../web/worker/searchWithAlgolia";
import { builder } from "../builder";
import { QuestionObj } from "./questions";
const SearchInput = builder.inputType("SearchInput", {
fields: (t) => ({
query: t.string({ required: true }),
starsThreshold: t.int({
description: "Minimum number of stars on a question",
}),
forecastsThreshold: t.int({
description: "Minimum number of forecasts on a question",
}),
forecastingPlatforms: t.stringList({
description: "List of platform ids to filter by",
}),
limit: t.int(),
}),
});
builder.queryField("searchQuestions", (t) =>
t.field({
type: [QuestionObj],
description:
"Search for questions; uses Algolia instead of the primary metaforecast database",
args: {
input: t.arg({ type: SearchInput, required: true }),
},
resolve: async (parent, { input }) => {
// defs
const query = input.query === undefined ? "" : input.query;
if (query === "") return [];
const forecastsThreshold = input.forecastsThreshold;
const starsThreshold = input.starsThreshold;
const platformsIncludeGuesstimate =
input.forecastingPlatforms?.includes("guesstimate") &&
starsThreshold <= 1;
// preparation
const unawaitedAlgoliaResponse = searchWithAlgolia({
queryString: query,
hitsPerPage: input.limit + 50,
starsThreshold,
filterByPlatforms: input.forecastingPlatforms,
forecastsThreshold,
});
let results: AlgoliaQuestion[] = [];
// consider the guesstimate and the non-guesstimate cases separately.
if (platformsIncludeGuesstimate) {
const [responsesNotGuesstimate, responsesGuesstimate] =
await Promise.all([
unawaitedAlgoliaResponse,
guesstimate.search(query),
]); // faster than two separate requests
results = [...responsesNotGuesstimate, ...responsesGuesstimate];
} else {
results = await unawaitedAlgoliaResponse;
}
return results.map((q) => ({
...q,
timestamp: new Date(q.timestamp),
}));
},
})
);