Skip to content

Commit

Permalink
🎉 add parent tags from tag graph to algolia chart records
Browse files Browse the repository at this point in the history
  • Loading branch information
ikesau committed Sep 5, 2024
1 parent e468790 commit cf9fb62
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
10 changes: 9 additions & 1 deletion baker/algolia/indexChartsToAlgolia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
countries,
orderBy,
removeTrailingParenthetical,
uniq,
} from "@ourworldindata/utils"
import { MarkdownTextWrap } from "@ourworldindata/components"
import { getAnalyticsPageviewsByUrlObj } from "../../db/model/Pageview.js"
Expand Down Expand Up @@ -162,6 +163,8 @@ const getChartsRecords = async (

const pageviews = await getAnalyticsPageviewsByUrlObj(knex)

const parentTagsByChildName = await db.getParentTagsByChildName(knex)

const records: ChartRecord[] = []
for (const c of parsedRows) {
// Our search currently cannot render explorers, so don't index them because
Expand All @@ -182,6 +185,11 @@ const getChartsRecords = async (
fontSize: 10, // doesn't matter, but is a mandatory field
}).plaintext

const parentTags = c.tags.flatMap(
// a chart can be tagged with a tag that isn't in the tag graph
(tag) => parentTagsByChildName[tag] || []
)

const record = {
objectID: c.id.toString(),
chartId: c.id,
Expand All @@ -193,7 +201,7 @@ const getChartsRecords = async (
numDimensions: parseInt(c.numDimensions),
publishedAt: c.publishedAt,
updatedAt: c.updatedAt,
tags: c.tags as any as string[],
tags: uniq([...c.tags, ...parentTags]),
keyChartForTags: c.keyChartForTags as string[],
titleLength: c.title.length,
// Number of references to this chart in all our posts and pages
Expand Down
47 changes: 45 additions & 2 deletions db/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
GRAPHER_DB_PORT,
} from "../settings/serverSettings.js"
import { registerExitHandler } from "./cleanup.js"
import { keyBy } from "@ourworldindata/utils"
import { createTagGraph, keyBy } from "@ourworldindata/utils"
import {
DbChartTagJoin,
ImageMetadata,
Expand All @@ -26,8 +26,10 @@ import {
DbPlainPostGdocLink,
OwidGdocLinkType,
OwidGdoc,
DbPlainTag,
TagGraphNode,
} from "@ourworldindata/types"
import { groupBy } from "lodash"
import { groupBy, uniq } from "lodash"
import { gdocFromJSON } from "./model/Gdoc/GdocFactory.js"

// Return the first match from a mysql query
Expand Down Expand Up @@ -527,6 +529,47 @@ export async function getFlatTagGraph(knex: KnexReadonlyTransaction): Promise<
return { ...tagGraphByParentId, __rootId: tagGraphRootIdResult.id }
}

// DFS through the tag graph and create a map of parent tags for each child tag
// e.g. { "Child": [ "Parent", "Grandparent" ], "Parent": [ "Grandparent" ] }
// parent tags are listed in no particular order
export async function getParentTagsByChildName(
trx: KnexReadonlyTransaction
): Promise<Record<DbPlainTag["name"], DbPlainTag["name"][]>> {
const { __rootId, ...flatTagGraph } = await getFlatTagGraph(trx)
const tagGraph = createTagGraph(flatTagGraph, __rootId)

const tagsById = await knexRaw<Pick<DbPlainTag, "id" | "name">>(
trx,
`-- sql
SELECT id, name FROM tags`
).then((tags) => keyBy(tags, "id"))

const parentTagsByChildName: Record<
DbPlainTag["name"],
DbPlainTag["name"][]
> = {}

function trackParents(node: TagGraphNode): void {
for (const child of node.children) {
trackParents(child)
}

const preexistingParents = parentTagsByChildName[node.name] ?? []
// node.path is an array of tag ids from the root to the current node
// slice to remove the root node and the current node, then map them into tag names
const newParents = node.path.slice(1, -1).map((id) => tagsById[id].name)

parentTagsByChildName[node.name] = uniq([
...preexistingParents,
...newParents,
])
}

trackParents(tagGraph)

return parentTagsByChildName
}

export async function updateTagGraph(
knex: KnexReadWriteTransaction,
tagGraph: FlatTagGraph
Expand Down

0 comments on commit cf9fb62

Please sign in to comment.