<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ IBM Watson - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ IBM Watson - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 18 Sep 2026 23:40:21 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/ibm-watson/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Have you had “The Talk” with your chatbot about graph data structures? ]]>
                </title>
                <description>
                    <![CDATA[ By Mark Watson A coming-of-age story for your database model _Image credit: [Charlotte Parent](http://www.charlotteparent.com/CLT/Health-Development/More-Than-the-Birds-and-the-Bees-Teaching-Your-Child-About-Healthy-Sexuality/" rel="noopener" target... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/have-you-had-the-talk-with-your-chatbot-about-graph-data-structures-3aaf5c3ae52c/</link>
                <guid isPermaLink="false">66c34c2ea1d481faeda49b6f</guid>
                
                    <category>
                        <![CDATA[ #chatbots ]]>
                    </category>
                
                    <category>
                        <![CDATA[ graph database ]]>
                    </category>
                
                    <category>
                        <![CDATA[ IBM Watson ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Recommendation System ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 19 Feb 2017 00:28:53 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*AeUDHuLM_pyfNZ3ZP5znyQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mark Watson</p>
<h4 id="heading-a-coming-of-age-story-for-your-database-model">A coming-of-age story for your database model</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*AeUDHuLM_pyfNZ3ZP5znyQ.png" alt="Image" width="800" height="533" loading="lazy">
_Image credit: [Charlotte Parent](http://www.charlotteparent.com/CLT/Health-Development/More-Than-the-Birds-and-the-Bees-Teaching-Your-Child-About-Healthy-Sexuality/" rel="noopener" target="<em>blank" title=")</em></p>
<p>Graph databases are a great way to store conversational data. A simple <a target="_blank" href="https://hackernoon.com/chatbot-architecture-496f5bf820ed#320b">dialog</a> <a target="_blank" href="https://en.wikipedia.org/wiki/Dialog_tree">tree</a> can add depth to character interactions in a video game. A <a target="_blank" href="https://gigaom.com/2013/05/15/how-google-is-setting-the-new-search-standard-with-voice-and-knowledge-graph/">knowledge</a> <a target="_blank" href="http://www.aclweb.org/anthology/N15-1086">graph</a> can extract more meaning from dialog to better understand how user intent relates to an application’s data.</p>
<p>In this article, I’ll show you a basic graph model for capturing chatbot interactions and how to persist them using the <a target="_blank" href="https://tinkerpop.apache.org/">Apache TinkerPop</a> framework. I’ll also show you some <a target="_blank" href="http://tinkerpop.apache.org/gremlin.html">Gremlin</a> queries for adding a recommendation feature to the chatbot. The source code and setup instructions for my example “Recipe Bot” are <a target="_blank" href="https://github.com/ibm-cds-labs/watson-recipe-bot-nodejs-graph">on GitHub</a>.</p>
<h3 id="heading-review-recipe-bot">Review: Recipe Bot</h3>
<p>The Recipe Bot is a <a target="_blank" href="https://api.slack.com/bot-users">Slack Bot User</a> that lets people request recipes based on specified ingredients or cuisines. Previously I showed you how to add support for users to request their favorite recipes, like so:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*SjILWmRnPN3sSdr133pHRg.png" alt="Image" width="540" height="274" loading="lazy"></p>
<p>The graph version of the bot has all of the same features I discussed in my <a target="_blank" href="https://medium.com/ibm-watson-data-lab/persisting-data-for-a-smarter-chatbot-be599480f7b2#.jvmry69xz">previous article on persisting metadata with JSON</a>, but with the graph version you’ll be adding recommendations.</p>
<h3 id="heading-how-it-works-with-tinkerpop">How it works with TinkerPop</h3>
<p>Here is an architecture diagram of how the bot works:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uGXlWtFX65TWPtvpKUkWGg.png" alt="Image" width="800" height="333" loading="lazy">
_My Recipe Bot. Hey! The diagram is actually an [undirected graph](https://en.wikipedia.org/wiki/Graph_theory" rel="noopener" target="<em>blank" title="). Who knew?</em></p>
<p>You’ll see that I’m using the Watson Conversation service. Watson Conversation lets me describe the flow of the conversation through the use of dialogs, and it helps me extract information and user intent from chat messages. You can code your own dialog tree and perform your own message parsing, or you can use tools like Watson Conversation or Botkit to help. Here is how the dialog tree for the Recipe Bot is modeled:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*qaJL5vQGKkhUCShVpiusGg.png" alt="Image" width="800" height="466" loading="lazy">
<em>The Watson Conversation UI. Graphs are everywhere.</em></p>
<p>You can follow a conversation through the dialog tree similar to how you can follow vertices and edges in a graph (after all, <a target="_blank" href="https://en.wikipedia.org/wiki/Tree_(graph_theory)">trees are graphs</a> too):</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*fzxYyM3iP9Qc08yu4spt_g.png" alt="Image" width="362" height="200" loading="lazy">
<em>It’s not much of a tree, but I’m keeping it simple, y’all.</em></p>
<p>In the simplified graph above, the Recipe Bot cares only about the progression between the major entities of the bot:</p>
<ol>
<li>People</li>
<li>Ingredients</li>
<li>Cuisines</li>
<li>Recipes</li>
</ol>
<h3 id="heading-data-model-amp-access-pattern">Data model &amp; access pattern</h3>
<p>As the conversation progresses, you store the following vertices and edges using the TinkerPop API:</p>
<ol>
<li><strong>Person vertex:</strong> For each person that interacts with the bot, store that person as a vertex in the graph.</li>
</ol>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"person"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"vertex"</span>,  <span class="hljs-string">"properties"</span>: {    <span class="hljs-string">"name"</span>: <span class="hljs-string">"U2JBLUPL2"</span>  }}
</code></pre><p><strong>2. Ingredient or cuisine vertex:</strong> When a person requests a specific ingredient or cuisine, you store that ingredient or cuisine — along with the list of recipes retrieved from <a target="_blank" href="https://spoonacular.com/food-api">Spoonacular</a> — as a vertex.</p>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"cuisine"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"vertex"</span>,  <span class="hljs-string">"properties"</span>: {    <span class="hljs-string">"name"</span>: <span class="hljs-string">"chinese"</span>,    <span class="hljs-string">"detail"</span>: <span class="hljs-string">"[{\"id\": 573147, \"title\": \"Kale Fried Rice\"..."</span>  }}
</code></pre><p><strong>3. Selects edge, person → (ingredient | cuisine):</strong> You create an edge, labelled <code>"selects"</code>, between the person and the ingredient or cuisine (that is, “person selects cuisine”). In addition, store a <code>"count"</code> property on the edge and increment its value each time the user requests the same ingredient or cuisine.</p>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"selects"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"edge"</span>,  <span class="hljs-string">"inV"</span>: <span class="hljs-number">4152</span>,  <span class="hljs-string">"outV"</span>: <span class="hljs-number">4224</span>,  <span class="hljs-string">"properties"</span>: {    <span class="hljs-string">"count"</span>: <span class="hljs-number">3</span>  }}
</code></pre><ol start="4">
<li><strong>Recipe vertex:</strong> When a user requests a recipe, store the recipe as a vertex.</li>
</ol>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"recipe"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"vertex"</span>,  <span class="hljs-string">"properties"</span>: {    <span class="hljs-string">"name"</span>: <span class="hljs-string">"573147"</span>,    <span class="hljs-string">"detail"</span>: <span class="hljs-string">"Ok, it takes *45* minutes to make...*"</span>,    <span class="hljs-string">"title"</span>: <span class="hljs-string">"Kale Fried Rice"</span>  }}
</code></pre><ol start="5">
<li><strong>Selects edge, (ingredient | cuisine) → recipe:</strong> You create another <code>"selects"</code> edge between the ingredient or cuisine and the recipe (that is, “cuisine selects recipe”). In addition, store a <code>"count"</code> property on the edge and increment it each time the ingredient or cuisine selects the same recipe.</li>
</ol>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"selects"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"edge"</span>,  <span class="hljs-string">"inV"</span>: <span class="hljs-number">4320</span>,  <span class="hljs-string">"outV"</span>: <span class="hljs-number">4152</span>,  <span class="hljs-string">"properties"</span>: {    <span class="hljs-string">"count"</span>: <span class="hljs-number">22</span>  }}
</code></pre><p><strong>6. Selects edge, person → recipe:</strong> You create yet another <code>"selects"</code> edge directly between the person and the recipe (that is, “person selects recipe”). Store a <code>"count"</code> property on the edge and increment it each time a person requests the same recipe.</p>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"selects"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"edge"</span>,  <span class="hljs-string">"inV"</span>: <span class="hljs-number">4320</span>,  <span class="hljs-string">"outV"</span>: <span class="hljs-number">4224</span>,  <span class="hljs-string">"properties"</span>: {    <span class="hljs-string">"count"</span>: <span class="hljs-number">4</span>  }}
</code></pre><p><strong>7. Has edge, recipe → (ingredient | cuisine):</strong> Finally, create an edge, labelled <code>"has"</code>, between the recipe and the ingredient or cuisine (that is, “recipe has cuisine”). This relationship allows you to find all the ingredients and cuisines that a recipe uses. There is no count field on this edge.</p>
<pre><code>{  <span class="hljs-string">"label"</span>: <span class="hljs-string">"has"</span>,  <span class="hljs-string">"type"</span>: <span class="hljs-string">"edge"</span>,  <span class="hljs-string">"inV"</span>: <span class="hljs-number">4152</span>,  <span class="hljs-string">"outV"</span>: <span class="hljs-number">4320</span>}
</code></pre><p>The graph for a single user looks something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*h6fvJxvuKB_6EVn-w1itTg.png" alt="Image" width="623" height="585" loading="lazy">
<em>This graph has it going on. It’s a [(weakly) connected graph](https://en.wikipedia.org/wiki/Connectivity</em>%28graph_theory%29#Definitions_of_components.2C_cuts_and_connectivity" rel="noopener" target="<em>blank" title="). There are all kinds of graphs.</em></p>
<p>So far, by using a graph database, you get the following benefits:</p>
<ol>
<li>Reduce third-party API calls by caching entities.</li>
<li>Provide a more personal experience for users by harnessing metadata on their interactions.</li>
</ol>
<p>A “more personal experience” for Recipe Bot means allowing users to request their favorite recipes. To find a user’s favorite recipes, you use the Gremlin <a target="_blank" href="http://tinkerpop.apache.org/docs/current/reference/#traversal">graph traversal</a> language. The following Gremlin query will give you a user’s top-five favorite recipes, sorted by count:</p>
<h3 id="heading-adding-recommendations">Adding recommendations</h3>
<p>Since you track every user interaction with the bot as a graph, you can find popular ingredients, cuisines, or recipes requested by all users. You can use Gremlin to find popular recipes based on an ingredient or cuisine. Here’s how it works:</p>
<p>Let’s say, a user is looking for recipes that use onions:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Yf49Io2lbpZeHrsvfyMxLA.png" alt="Image" width="800" height="374" loading="lazy"></p>
<p>You can find popular recipes that use onions by issuing the following query. (I’ll unpack it further below—don’t worry!):</p>
<p>This query says, “Give me anyone, excluding the calling user, who has requested recipes more than once that have onions.” It breaks down like so:</p>
<ol>
<li>Start with <code>"onions"</code>:</li>
</ol>
<pre><code>g.V().hasLabel(<span class="hljs-string">"ingredient"</span>).has(<span class="hljs-string">"name"</span>,<span class="hljs-string">"onions"</span>)
</code></pre><ol start="2">
<li>Get the recipes that have <code>"onions"</code>. This API call uses the <code>"has"</code> edge coming from the recipe vertex into the ingredient vertex. Using <code>.in()</code> skips the edge and only returns the recipe vertex. (You don’t need any properties from the edge object, so there’s no reason to return it here.)</li>
</ol>
<pre><code>.in(<span class="hljs-string">"has"</span>)
</code></pre><ol start="3">
<li>Get the users that have requested these recipes more than once. This call uses the <code>"selects"</code> edge coming from the person to the recipe:</li>
</ol>
<pre><code>.inE().has(<span class="hljs-string">"count"</span>,gt(<span class="hljs-number">1</span>)).order().by(<span class="hljs-string">"count"</span>, decr)
</code></pre><ol start="4">
<li>Get the users, excluding the current user:</li>
</ol>
<pre><code>.outV().hasLabel(<span class="hljs-string">"person"</span>).has(<span class="hljs-string">"name"</span>,neq(<span class="hljs-string">"CURRENT_USER"</span>))
</code></pre><ol start="5">
<li>Get the full path:</li>
</ol>
<pre><code>.path()
</code></pre><p>This call returns an array of matching paths that looks like this:</p>
<blockquote>
<p>ingredient ← recipe ← edge ← person</p>
</blockquote>
<p>You can access these recommended recipes at index 1.</p>
<p>When you return this recipe list to the user, the app puts the recommended recipes at the top and highlights the number of users who have previously used which recipe:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*HS0ft98ZPG4AezihLIHnFA.png" alt="Image" width="800" height="218" loading="lazy"></p>
<h3 id="heading-whats-next">What’s Next?</h3>
<p>Try a deployment for yourself. The <a target="_blank" href="https://github.com/ibm-cds-labs/watson-recipe-bot-nodejs-graph#watson-recipe-bot--ibm-graph">project’s README</a> has step-by-step instructions for completing your first deployment on IBM Bluemix. There’s also a <a target="_blank" href="https://github.com/ibm-cds-labs/watson-recipe-bot-java-graph">Java port</a> of the example app.</p>
<p>If you’re already using a dialog tree in your applications and want to use a graph database to persist metadata on interactions, I hope the source code in the repo above gives you some ideas on delivering more personalized experiences to your users.</p>
<p>And if you’ve enjoyed this article, please hit the ol’ ♥ so other Medium users might find it and dig it too. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
