Skip to content

BuildNot yet confirmed elsewhere1 publisher3 min readPublished

A depth-bounded Cypher path returns each ASML supply link with the article that established it

Multi-hop supply questions are cheap to ask in Cypher and awkward everywhere else. The traversal only holds if every article's name for a company lands on the same node. The post breaks off before that gets solved.

The Engineer · Build desk

How we use AISend a correction

Illustration accompanying A depth-bounded Cypher path returns each ASML supply link with the article that established it
Generated illustration

What happened

  • The build log's working query is Cypher: it matches SUPPLY_CUT, EXPORT_RESTRICTION and PRODUCTION_DELAY edges one to four hops out from ASML and returns each path with the article ID and event date on every link.
  • The full-text attempt over an Elasticsearch index of 9,414 English economic news articles returned fourteen hits, none of them the NVIDIA articles, because NVIDIA is not mentioned in any of the fourteen.
  • The relational attempt stored one row per event in an article_events table, which meant one CTE per hop and a hop count that had to be fixed before the query ran.

Why it matters

  • constraint A fixed-hop SQL query cannot report that it stopped early, so a five-link chain and a chain that does not exist return the same empty result and the same false comfort.
  • decision Choosing traversal promotes entity resolution from housekeeping to a build-time dependency, because every unresolved alias truncates paths that would otherwise connect.
  • exposure At roughly 29 extracted edges per article with no published precision, the people relying on this graph are exposed to single bad extractions that surface as paths with article IDs attached.
  • capability Because depth is a query-time parameter, re-asking the same supply-chain question at six hops costs a keystroke rather than a schema change and a rewrite.

Run the pattern and Neo4j hands back path objects rather than tuples [1][2]. The load-bearing part is not the variable-length arrow, it is the two list comprehensions in the RETURN clause: `[r IN relationships(path) | r.article_id]` walks every edge of a matched path and pulls the article that established it, and its sibling does the same for `event_date` [1]. A four-hop result therefore arrives carrying four article IDs and four dates, one per link, instead of a single provenance stamp on the endpoint [2]. With the `LIMIT 30` in place, one run can return up to 120 article references for a human to check [23].

The two attempts that failed did so for unrelated reasons, which is easy to lose in the retelling. Elasticsearch was asked a question about text and answered it: fourteen documents matched the phrasing, and the NVIDIA articles were not among them because NVIDIA is not named in any of them [6][7]. The author is explicit that relevance tuning would not have closed that gap [7]. SQL failed on two counts. The visible one is hop count, two CTEs for two hops, three for three, depth fixed before the query runs [10]. The quieter one is arity: an article describing an event involving three or four companies does not reduce to one subject-object row without discarding something [13]. Worth noting that the Cypher pattern also runs company to company [1], so a four-participant event still has to be decomposed into pairwise edges or into an event node the post does not show. The graph relaxes the row shape, but modeling an event with four participants takes more structure than that alone provides [13].

The ratios are worth doing. 275,293 relationships over 9,414 articles is 29.2 edges per article [19]; 84,962 nodes over the same corpus is 9.0 nodes per article [20]; the graph averages 3.2 relationships per node [21]. That density is a claim about an extraction pipeline, not about Neo4j. For it to transfer, your articles would have to name companies at a similar rate and your extractor would have to be as willing to emit an edge. No precision figure is reported for any of the 275,293 [14], and a bad edge does not look bad in the output; it looks like a path with an article ID attached [2].

Latency is the figure missing here. Response time on the Cypher query is described as acceptable, but the post gives no number, no hardware detail, and no comparison against a deeper bound [15]. A benchmark table would at least be something to argue with. What the post does name as the unfinished dependency is entity resolution: the traversal only works if the same company maps to the same node however an article refers to it, and that did not happen automatically [17]. Filings say ASML Holding NV, a wire shortens it to ASML, and a blog post never names the company and calls it the Dutch lithography equipment maker [18]. Left unresolved those are three nodes, and the source text breaks off mid-sentence on exactly that failure [24].

The semantics of an empty result are stated carefully, and that carries more weight than it sounds: no path returned means the graph holds no evidence for the connection, not that the connection is absent in the world [16]. Combined with a depth bound tuned at query time [3], that supports an honest workflow. Ask at four hops, ask at six, and read both answers as statements about corpus coverage rather than about semiconductors. It also means the graph inherits every gap in the 9,414 articles [5], which is a fair trade for a research tool and a poor one for anything that has to be right before someone opens the cited articles.

What to watch

  • Whether part 3 resolves entities with a deterministic alias table or embedding-based coreference, and what that does to the 84,962 node count.
  • Any reported precision figure for the extracted relationships, since one wrong edge produces a path that reads like sourced evidence.
  • A measured latency number at depth five or six on the same graph, which is where variable-length expansion normally starts to hurt.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence52
Adoption12
Hype gap+10
Incentives32
Confidence55
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    The working query is Cypher: MATCH path = (source:Company {name: "ASML"}) -[:SUPPLY_CUT|EXPORT_RESTRICTION|PRODUCTION_DELAY*1..4]-> (downstream:Company), returning downstream.name, length(path) as hops, [r IN relationships(path) | r.article_id] as evidence_articles and [r IN relationships(path) | r.event_date] as event_dates, ordered by hops and first event date, LIMIT 30. The pattern runs company node to company node.

    ReportedSupportedView cited source
  2. [2]

    The author states the query returns paths, not rows: each result is a chain from the source company to a downstream company with the article ID and event date at every link, not just at the endpoint.

    ReportedSupportedView cited source
  3. [3]

    The *1..4 depth bound is a parameter the author tunes at query time; checking four hops required no rewriting.

    ReportedSupportedView cited source

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · August 28, 2026

    Building an investing knowledge graph, part 2: the query SQL can't answer

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

Loading related stories