<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: NIKITHA</title>
    <description>The latest articles on DEV Community by NIKITHA (@nikitha_8ca3ffcc07cf331e2).</description>
    <link>https://dev.to/nikitha_8ca3ffcc07cf331e2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3976186%2F3cd8970a-7ecb-4481-8111-4094e319692b.jpg</url>
      <title>DEV Community: NIKITHA</title>
      <link>https://dev.to/nikitha_8ca3ffcc07cf331e2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nikitha_8ca3ffcc07cf331e2"/>
    <language>en</language>
    <item>
      <title>We went Edgemaxxing and FalkorDB mogged Joins</title>
      <dc:creator>NIKITHA</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:43:48 +0000</pubDate>
      <link>https://dev.to/nikitha_8ca3ffcc07cf331e2/we-went-edgemaxxing-and-falkordb-mogged-joins-3lbf</link>
      <guid>https://dev.to/nikitha_8ca3ffcc07cf331e2/we-went-edgemaxxing-and-falkordb-mogged-joins-3lbf</guid>
      <description>&lt;p&gt;Here is how we did it, Edgemaxxing is really good (for performance).&lt;/p&gt;




&lt;h2&gt;
  
  
  Background you need first
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a graph database?
&lt;/h3&gt;

&lt;p&gt;A graph database stores two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nodes:&lt;/strong&gt; things. For example: a paper, a finding, a hypothesis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges:&lt;/strong&gt; connections between two things. For example: "this finding is evidence for this hypothesis".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both nodes and edges can hold &lt;strong&gt;properties&lt;/strong&gt;, which are small pieces of data such as &lt;code&gt;year: 2026&lt;/code&gt; or &lt;code&gt;stance: "refutes"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;FalkorDB is a graph database. You talk to it with a query language called &lt;strong&gt;Cypher&lt;/strong&gt;. A Cypher pattern looks like a drawing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;finding&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:EVIDENCE_FOR&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hypothesis&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That reads as "a finding, connected by an EVIDENCE_FOR edge, to a hypothesis".&lt;/p&gt;

&lt;h3&gt;
  
  
  Terms
&lt;/h3&gt;

&lt;p&gt;These are relevant to the problems we are solving so its good to know, But it should work generally for other use cases as well! &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Word&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Question&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What the user types&lt;/td&gt;
&lt;td&gt;"creatine on intelligence vs muscle gain"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hypothesis&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One testable claim from the question&lt;/td&gt;
&lt;td&gt;H2: "Creatine increases muscle gain in adults"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Paper&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A published article&lt;/td&gt;
&lt;td&gt;Chen 2026 (a meta-analysis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Study&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One experiment inside a paper&lt;/td&gt;
&lt;td&gt;An RCT with 15 vegans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Finding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One measured result from a study&lt;/td&gt;
&lt;td&gt;"Skeletal muscle mass: no change"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concept&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A topic or measurement&lt;/td&gt;
&lt;td&gt;"lean mass"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Part 1: Edgemaxxing begins
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Lets look at an example "Lean mass increased by 0.37 kg."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For a hypothesis H2 (creatine increases muscle gain), this finding &lt;strong&gt;supports&lt;/strong&gt; it.&lt;/li&gt;
&lt;li&gt;For a different hypothesis, such as "creatine harms kidneys", it is &lt;strong&gt;not relevant&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So "supports" is not a fact about the finding alone. It is a fact about &lt;strong&gt;the finding together with one hypothesis&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bad solution
&lt;/h3&gt;

&lt;p&gt;Store &lt;code&gt;stance: "supports"&lt;/code&gt; on the finding node. Then the second hypothesis breaks: it sees "supports" too, which is wrong. You would have to copy the finding once per hypothesis, and the copies would drift apart.&lt;/p&gt;

&lt;h3&gt;
  
  
  What we did
&lt;/h3&gt;

&lt;p&gt;We put the stance on the &lt;strong&gt;edge&lt;/strong&gt; between the finding and the hypothesis i.e Edgemaxxing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;Finding:&lt;/span&gt; &lt;span class="s2"&gt;"Lean mass ↑ 0.37 kg"&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:EVIDENCE_FOR&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;stance:&lt;/span&gt; &lt;span class="s2"&gt;"supports"&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;weight&lt;/span&gt;&lt;span class="dl"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.67&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;There is one finding node.&lt;/li&gt;
&lt;li&gt;There is one edge per hypothesis, and each edge has its own stance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9qn6a4al1n1sgvv38p8v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9qn6a4al1n1sgvv38p8v.gif" alt=" " width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On the finding, “supports” can't say which hypothesis it means. On the edge, it can.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relevant bit:&lt;/strong&gt; many databases can't store properties on a connection, or make it awkward. FalkorDB is a &lt;strong&gt;property graph&lt;/strong&gt;, so edges can hold data just like nodes can. This one feature makes the whole design possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;Papers and findings are &lt;strong&gt;shared across all questions&lt;/strong&gt;. When a new question needs a paper that was already read, the app does not read it again. It only adds new &lt;code&gt;EVIDENCE_FOR&lt;/code&gt; edges. That saves LLM cost and time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: Make each contradiction an edge, tied to one hypothesis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Two findings can disagree for one hypothesis and not for another.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For a hypothesis H2, "lean mass ↑" (Naddafha 2026) and "skeletal muscle mass: no change" (Chen 2026) &lt;strong&gt;disagree&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For a kidney hypothesis, the same two findings say nothing, so there is no disagreement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What we did
&lt;/h3&gt;

&lt;p&gt;Edgemaxxing again! A contradiction is an edge between two findings, and it records &lt;strong&gt;which hypothesis&lt;/strong&gt; it belongs to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Naddafha&lt;/span&gt; &lt;span class="n"&gt;finding&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:CONTRADICTS&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;hypothesis:&lt;/span&gt; &lt;span class="s2"&gt;"H2"&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;reason:&lt;/span&gt; &lt;span class="s2"&gt;"different population"&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
                                   &lt;span class="py"&gt;explained_by:&lt;/span&gt; &lt;span class="s2"&gt;"postmenopausal women vs all women"&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Chen&lt;/span&gt; &lt;span class="n"&gt;finding&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MERGE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;e:&lt;/span&gt;&lt;span class="n"&gt;CONTRADICTS&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;hypothesis:&lt;/span&gt;&lt;span class="n"&gt;$k&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;e.reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;...&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e.severity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;...&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e.explained_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relevant bit:&lt;/strong&gt; &lt;code&gt;MERGE&lt;/code&gt; means "create it only if it does not exist yet".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc1kp90nlazsr7m6gfbb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc1kp90nlazsr7m6gfbb.gif" alt=" " width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The index
&lt;/h3&gt;

&lt;p&gt;To show the contradictions for H2, the app asks: "give me every &lt;code&gt;CONTRADICTS&lt;/code&gt; edge where &lt;code&gt;hypothesis = H2&lt;/code&gt;". Without help, FalkorDB would have to check &lt;strong&gt;every&lt;/strong&gt; contradiction edge in the whole graph.&lt;/p&gt;

&lt;p&gt;So we created an &lt;strong&gt;index&lt;/strong&gt; on that edge property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;r:&lt;/span&gt;&lt;span class="n"&gt;CONTRADICTS&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r.hypothesis&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relevant bit:&lt;/strong&gt; an index is like the index at the back of a book. Instead of reading every page, you jump straight to the right page. Most databases only index nodes or rows. FalkorDB can also index &lt;strong&gt;edges&lt;/strong&gt;, which is what makes this lookup fast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe76s3t1zehcocg66ng65.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe76s3t1zehcocg66ng65.gif" alt=" " width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: Recognise the same outcome under different names
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Paper A says "fat-free mass". Paper B says "lean body mass". Paper C says "FFM". These are almost the same measurement. If the app only matched exact words, it would miss real disagreements between these papers.&lt;/p&gt;

&lt;h3&gt;
  
  
  What we did
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Each &lt;strong&gt;Concept&lt;/strong&gt; node has a &lt;code&gt;synonyms&lt;/code&gt; list (other names for the same thing).&lt;/li&gt;
&lt;li&gt;When the &lt;strong&gt;Stance agent&lt;/strong&gt; (an LLM) judges a finding, it also answers: "does this finding measure the hypothesis's outcome, even under another name?" (&lt;code&gt;same_outcome: true/false&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;If yes, the code adds a special edge from the finding to the hypothesis's own outcome concept:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;   &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;Finding:&lt;/span&gt; &lt;span class="s2"&gt;"FFM ↑ 1.15 kg"&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:MEASURES&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;hypothesis:&lt;/span&gt; &lt;span class="s2"&gt;"H2"&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;Concept:&lt;/span&gt; &lt;span class="s2"&gt;"muscle gain"&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The code also &lt;strong&gt;adds the finding's wording to the concept's synonyms&lt;/strong&gt;. Next time, "FFM" is already known as a name for that outcome, with no LLM needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhsv8j2ma93f3cutf0mor.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhsv8j2ma93f3cutf0mor.gif" alt=" " width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relevant bit:&lt;/strong&gt; this &lt;code&gt;MEASURES&lt;/code&gt; edge also carries &lt;code&gt;hypothesis&lt;/code&gt;, for the same reason as Part 2: "FFM counts as muscle gain" is true for H2, but maybe not for some other hypothesis. It has an edge index too. Again Edgemaxxing!!!!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;The graph &lt;strong&gt;learns names over time&lt;/strong&gt;. Every question makes the synonym lists better for the next question.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4: Contradiction camps with &lt;code&gt;algo.WCC&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What it does
&lt;/h3&gt;

&lt;p&gt;Imagine the contradiction edges as strings tied between findings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If A contradicts B, and B contradicts C, then A, B and C are all tied together.&lt;/li&gt;
&lt;li&gt;Each group of tied-together findings is one &lt;strong&gt;"camp"&lt;/strong&gt;: one area where the evidence argues with itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;WCC&lt;/strong&gt; ("weakly connected components") is the standard algorithm that finds these groups.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fur2fvxquf45d1cpg0zq8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fur2fvxquf45d1cpg0zq8.gif" alt=" " width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Relevant bit:&lt;/strong&gt; FalkorDB ships graph algorithms built in, so the app calls &lt;code&gt;CALL algo.WCC(...)&lt;/code&gt; inside the database. It doesn't have to download the whole graph and run the algorithm in Python.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;CALL&lt;/span&gt; &lt;span class="n"&gt;algo.WCC&lt;/span&gt;&lt;span class="ss"&gt;({&lt;/span&gt;&lt;span class="py"&gt;nodeLabels:&lt;/span&gt; &lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Finding'&lt;/span&gt;&lt;span class="ss"&gt;],&lt;/span&gt; &lt;span class="py"&gt;relationshipTypes:&lt;/span&gt; &lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'CONTRADICTS'&lt;/span&gt;&lt;span class="ss"&gt;]})&lt;/span&gt;
&lt;span class="k"&gt;YIELD&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;componentId&lt;/span&gt;
&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;e:&lt;/span&gt;&lt;span class="n"&gt;EVIDENCE_FOR&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;h:&lt;/span&gt;&lt;span class="n"&gt;Hypothesis&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:ASKS&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Question&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;id:&lt;/span&gt;&lt;span class="n"&gt;$q&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;componentId&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;findings&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;e.stance&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;stances&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;findings&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;h.statement&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;hypothesis&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;componentId&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;camp&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findings&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stances&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In plain words: find the camps across all findings, then keep only the ones in this question, and show each camp's size and stances.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;One limitation:&lt;/strong&gt; WCC runs over &lt;strong&gt;all&lt;/strong&gt; &lt;code&gt;CONTRADICTS&lt;/code&gt; edges, for every hypothesis. If one finding has contradictions under two different hypotheses, those two camps can join into one.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  How it all fits together
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dot"&gt;&lt;code&gt;&lt;span class="nv"&gt;Paper&lt;/span&gt; &lt;span class="err"&gt;─&lt;/span&gt;&lt;span class="nv"&gt;DESCRIBES&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nv"&gt;Study&lt;/span&gt; &lt;span class="err"&gt;─&lt;/span&gt;&lt;span class="nv"&gt;FOUND&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nv"&gt;Finding&lt;/span&gt; &lt;span class="err"&gt;─&lt;/span&gt;&lt;span class="nv"&gt;EVIDENCE_FOR&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;stance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nv"&gt;Hypothesis&lt;/span&gt;
                                   &lt;span class="err"&gt;│&lt;/span&gt;
                                   &lt;span class="err"&gt;├─&lt;/span&gt;&lt;span class="nv"&gt;MEASURES&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;hypothesis&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nv"&gt;Concept&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;synonyms&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                                   &lt;span class="err"&gt;│&lt;/span&gt;
                                   &lt;span class="err"&gt;└─&lt;/span&gt;&lt;span class="nv"&gt;CONTRADICTS&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;hypothesis&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reason&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;explained_by&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nv"&gt;Finding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Parting Notes
&lt;/h2&gt;

&lt;p&gt;Edges are the core feature of graph dbs. Using them effectively can make your life easier (and faster!!!).&lt;/p&gt;

</description>
      <category>backend</category>
      <category>database</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
