The original (unsuccessful) basic search query
Lowercased terms to skip (e.g. previously searched, zero-result queries)
The advanced query string, or undefined if there is nothing worth suggesting
await suggestAdvancedQuery("acetone", new Set(["acetone"]));
// Returns: "2-propanone OR propanone OR propan-2-one OR 67-64-1"
export async function suggestAdvancedQuery(
query: string,
excluded: ReadonlySet<string>,
): Promise<string | undefined> {
const ranked = await getRankedNamesByName(query);
if (!ranked) return undefined;
const seen = new Set<string>([query.trim().toLowerCase(), ...excluded]);
const take = (entry: string): boolean => {
const key = entry.toLowerCase();
if (seen.has(key) || entry.includes('"')) return false;
seen.add(key);
return true;
};
const names = ranked
.filter((entry) => !isCAS(entry))
.filter(take)
.slice(0, ADVANCED_QUERY_NAME_COUNT)
.map((entry) => quoteAdvancedTerm(formatSuggestedName(entry)));
const cas = ranked.find((entry) => isCAS(entry) && take(entry));
const terms = cas ? [...names, cas] : names;
if (terms.length < 2) return undefined;
const advanced = terms.join(' OR ');
return hasAdvancedSyntax(advanced) ? advanced : undefined;
}
Suggests an advanced (AST) search for a query that returned no results. Combines the three most common PubChem names for the compound, plus its CAS number, with
OR. The original query (and any term inexcluded) is left out of the result, since it is already known to find nothing. Returns undefined when PubChem has no match or fewer than two terms remain.