You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/10/13 15:27:45 UTC

svn commit: r1764708 [1/2] - in /tinkerpop/site/docs/3.2.3-SNAPSHOT: ./ dev/provider/ images/ recipes/ reference/

Author: spmallette
Date: Thu Oct 13 15:27:45 2016
New Revision: 1764708

URL: http://svn.apache.org/viewvc?rev=1764708&view=rev
Log:
Deploy docs for TinkerPop 3.2.3-SNAPSHOT

Added:
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/gremlin-recommendation.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-1.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-2.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-3.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-4.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-1.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-2.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-3.png   (with props)
    tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-4.png   (with props)
Modified:
    tinkerpop/site/docs/3.2.3-SNAPSHOT/dev/provider/index.html
    tinkerpop/site/docs/3.2.3-SNAPSHOT/index.html
    tinkerpop/site/docs/3.2.3-SNAPSHOT/recipes/index.html
    tinkerpop/site/docs/3.2.3-SNAPSHOT/reference/index.html

Modified: tinkerpop/site/docs/3.2.3-SNAPSHOT/dev/provider/index.html
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/dev/provider/index.html?rev=1764708&r1=1764707&r2=1764708&view=diff
==============================================================================
--- tinkerpop/site/docs/3.2.3-SNAPSHOT/dev/provider/index.html (original)
+++ tinkerpop/site/docs/3.2.3-SNAPSHOT/dev/provider/index.html Thu Oct 13 15:27:45 2016
@@ -2411,9 +2411,9 @@ twenty. Under this model, the amount of
 <pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; cluster = Cluster.open()
 ==&gt;localhost/<span class="float">127.0</span><span class="float">.0</span><span class="float">.1</span>:<span class="integer">8182</span>
 gremlin&gt; client = cluster.connect()
-==&gt;org.apache.tinkerpop.gremlin.driver.Client<span class="error">$</span>ClusteredClient<span class="error">@</span><span class="float">29f</span><span class="integer">95272</span>
+==&gt;org.apache.tinkerpop.gremlin.driver.Client<span class="error">$</span>ClusteredClient<span class="annotation">@c754401</span>
 gremlin&gt; aliased = client.alias(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>)
-==&gt;org.apache.tinkerpop.gremlin.driver.Client<span class="error">$</span>AliasClusteredClient<span class="error">@</span><span class="float">1d</span>bff71c
+==&gt;org.apache.tinkerpop.gremlin.driver.Client<span class="error">$</span>AliasClusteredClient<span class="error">@</span><span class="integer">93</span>ce24d
 gremlin&gt; g = org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph.INSTANCE.traversal() <span class="comment">//</span><b>(1)</b>
 ==&gt;graphtraversalsource[emptygraph[empty], standard]
 gremlin&gt; rs = aliased.submit(g.V().both().barrier().both().barrier()).all().get() <span class="comment">//</span><b>(2)</b>
@@ -3039,7 +3039,7 @@ to provide a way to dynamically evaluate
 </div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2016-10-12 14:39:56 -04:00
+Last updated 2016-10-13 10:18:08 -04:00
 </div>
 </div>
 </body>

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/gremlin-recommendation.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/gremlin-recommendation.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/gremlin-recommendation.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-1.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-1.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-1.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-2.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-2.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-2.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-3.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-3.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-3.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-4.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-4.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommedation-alice-4.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-1.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-1.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-1.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-2.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-2.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-2.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-3.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-3.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-3.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-4.png
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-4.png?rev=1764708&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tinkerpop/site/docs/3.2.3-SNAPSHOT/images/recommendation-alice-4.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: tinkerpop/site/docs/3.2.3-SNAPSHOT/index.html
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/index.html?rev=1764708&r1=1764707&r2=1764708&view=diff
==============================================================================
--- tinkerpop/site/docs/3.2.3-SNAPSHOT/index.html (original)
+++ tinkerpop/site/docs/3.2.3-SNAPSHOT/index.html Thu Oct 13 15:27:45 2016
@@ -895,6 +895,12 @@ and an overview of Gremlin. (<strong>ext
 <div class="ulist">
 <ul>
 <li>
+<p>Rodriguez, M.A., <a href="http://www.datastax.com/dev/blog/gremlins-time-machine">"Gremlin&#8217;s Time Machine,"</a> DataStax Engineering Blog, September 2016.</p>
+</li>
+<li>
+<p>Rodriguez, M.A., <a href="http://www.slideshare.net/slidarko/gremlins-graph-traversal-machinery">"Gremlin&#8217;s Graph Traversal Machinery,"</a> Cassandra Summit, September 2016.</p>
+</li>
+<li>
 <p>Rodriguez, M.A., <a href="http://www.datastax.com/dev/blog/the-mechanics-of-gremlin-olap">"The Mechanics of Gremlin OLAP,"</a> DataStax Engineering Blog, April 2016.</p>
 </li>
 <li>
@@ -956,7 +962,7 @@ Reference Documentation for providers an
 </div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2016-10-04 11:56:22 -04:00
+Last updated 2016-10-13 11:25:27 -04:00
 </div>
 </div>
 </body>

Modified: tinkerpop/site/docs/3.2.3-SNAPSHOT/recipes/index.html
URL: http://svn.apache.org/viewvc/tinkerpop/site/docs/3.2.3-SNAPSHOT/recipes/index.html?rev=1764708&r1=1764707&r2=1764708&view=diff
==============================================================================
--- tinkerpop/site/docs/3.2.3-SNAPSHOT/recipes/index.html (original)
+++ tinkerpop/site/docs/3.2.3-SNAPSHOT/recipes/index.html Thu Oct 13 15:27:45 2016
@@ -813,6 +813,7 @@ span.line-numbers { border-right: 1px so
 <li><a href="#cycle-detection">Cycle Detection</a></li>
 <li><a href="#if-then-based-grouping">If-Then Based Grouping</a></li>
 <li><a href="#pagination">Pagination</a></li>
+<li><a href="#recommendation">Recommendation</a></li>
 <li><a href="#shortest-path">Shortest Path</a></li>
 <li><a href="#traversal-induced-values">Traversal Induced Values</a></li>
 </ul>
@@ -1530,6 +1531,296 @@ gremlin&gt; t.next(<span class="integer"
 </div>
 </div>
 <div class="sect1">
+<h2 id="recommendation">Recommendation</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p><span class="image" style="float: left"><img src="../images/gremlin-recommendation.png" alt="gremlin-recommendation" width="180"></span>One of the more common use cases for a graph database is the
+development of <a href="https://en.wikipedia.org/wiki/Recommender_system">recommendation systems</a> and a simple approach to
+doing that is through <a href="https://en.wikipedia.org/wiki/Collaborative_filtering">collaborative filtering</a>.
+Collaborative filtering assumes that if a person shares one set of opinions with a different person, they are likely to
+have similar taste with respect to other issues. With that basis in mind, it is then possible to make predictions for a
+specific person as to what their opinions might be.</p>
+</div>
+<div class="paragraph">
+<p>As a simple example, consider a graph that contains "person" and "product" vertices connected by "bought" edges. The
+following script generates some data for the graph using that basic schema:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.addV(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).property(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+           addV(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).property(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">bob</span><span class="delimiter">&quot;</span></span>).
+           addV(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).property(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">jon</span><span class="delimiter">&quot;</span></span>).
+           addV(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).property(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">jack</span><span class="delimiter">&quot;</span></span>).
+           addV(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).property(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">jill</span><span class="delimiter">&quot;</span></span>)iterate()
+gremlin&gt; (<span class="integer">1</span>..<span class="integer">10</span>).each {
+           g.addV(<span class="string"><span class="delimiter">&quot;</span><span class="content">product</span><span class="delimiter">&quot;</span></span>).property(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">product #</span><span class="inline"><span class="inline-delimiter">${</span><span class="local-variable">it</span><span class="inline-delimiter">}</span></span><span class="delimiter">&quot;</span></span>).iterate()
+         }; <span class="type">[]</span>
+gremlin&gt; (<span class="integer">3</span>..<span class="integer">7</span>).each {
+           g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).
+             V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">product</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">product #</span><span class="inline"><span class="inline-delimiter">${</span><span class="local-variable">it</span><span class="inline-delimiter">}</span></span><span class="delimiter">&quot;</span></span>).addE(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).from(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).iterate()
+         }; <span class="type">[]</span>
+gremlin&gt; (<span class="integer">1</span>..<span class="integer">5</span>).each {
+           g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">bob</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).
+             V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">product</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">product #</span><span class="inline"><span class="inline-delimiter">${</span><span class="local-variable">it</span><span class="inline-delimiter">}</span></span><span class="delimiter">&quot;</span></span>).addE(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).from(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).iterate()
+         }; <span class="type">[]</span>
+gremlin&gt; (<span class="integer">6</span>..<span class="integer">10</span>).each {
+           g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">jon</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).
+             V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">product</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">product #</span><span class="inline"><span class="inline-delimiter">${</span><span class="local-variable">it</span><span class="inline-delimiter">}</span></span><span class="delimiter">&quot;</span></span>).addE(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).from(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).iterate()
+         }; <span class="type">[]</span>
+gremlin&gt; <span class="integer">1</span>.step(<span class="integer">10</span>, <span class="integer">2</span>) {
+           g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">jack</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).
+             V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">product</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">product #</span><span class="inline"><span class="inline-delimiter">${</span><span class="local-variable">it</span><span class="inline-delimiter">}</span></span><span class="delimiter">&quot;</span></span>).addE(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).from(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).iterate()
+         }; <span class="type">[]</span>
+gremlin&gt; <span class="integer">2</span>.step(<span class="integer">10</span>, <span class="integer">2</span>) {
+           g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">jill</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).
+             V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">product</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">product #</span><span class="inline"><span class="inline-delimiter">${</span><span class="local-variable">it</span><span class="inline-delimiter">}</span></span><span class="delimiter">&quot;</span></span>).addE(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).from(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>).iterate()
+         }; <span class="type">[]</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The first step to making a recommedation to "alice" using collaborative filtering is to understand what she bought:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">alice</span><span class="delimiter">'</span></span>).out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).values(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>)
+==&gt;product <span class="error">#</span><span class="integer">5</span>
+==&gt;product <span class="error">#</span><span class="integer">6</span>
+==&gt;product <span class="error">#</span><span class="integer">7</span>
+==&gt;product <span class="error">#</span><span class="integer">3</span>
+==&gt;product <span class="error">#</span><span class="integer">4</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The following diagram depicts one of the edges traversed in the above example between "alice" and "product #5".
+Obviously, the other products "alice" bought would have similar relations, but this diagram and those to follow will
+focus on the neighborhood around that product.</p>
+</div>
+<div class="paragraph">
+<p><span class="image"><img src="../images/recommendation-alice-1.png" alt="recommendation-alice-1" width="500"></span></p>
+</div>
+<div class="paragraph">
+<p>The next step is to determine who else purchased those products:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">alice</span><span class="delimiter">'</span></span>).out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).in(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).dedup().values(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>)
+==&gt;alice
+==&gt;bob
+==&gt;jack
+==&gt;jill
+==&gt;jon</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>It is worth noting that "alice" is in the results above. She should really be excluded from the list as the
+interest is in what individuals other than herself purchased:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">alice</span><span class="delimiter">'</span></span>).as(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>).
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).
+               in(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).where(neq(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>)).
+               dedup().values(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>)
+==&gt;bob
+==&gt;jack
+==&gt;jill
+==&gt;jon</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The following diagram shows "alice" and those others who purchased "product #5".</p>
+</div>
+<div class="paragraph">
+<p><span class="image"><img src="../images/recommendation-alice-2.png" alt="recommendation-alice-2" width="600"></span></p>
+</div>
+<div class="paragraph">
+<p>The knowledge of the people who bought the same things as "alice" can then be used to find the set of products that
+they bought:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">alice</span><span class="delimiter">'</span></span>).as(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>).
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).
+               in(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).where(neq(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>)).
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).
+               dedup().values(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>)
+==&gt;product <span class="error">#</span><span class="integer">1</span>
+==&gt;product <span class="error">#</span><span class="integer">2</span>
+==&gt;product <span class="error">#</span><span class="integer">3</span>
+==&gt;product <span class="error">#</span><span class="integer">4</span>
+==&gt;product <span class="error">#</span><span class="integer">5</span>
+==&gt;product <span class="error">#</span><span class="integer">7</span>
+==&gt;product <span class="error">#</span><span class="integer">9</span>
+==&gt;product <span class="error">#</span><span class="integer">6</span>
+==&gt;product <span class="error">#</span><span class="integer">8</span>
+==&gt;product <span class="error">#</span><span class="integer">10</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p><span class="image"><img src="../images/recommendation-alice-3.png" alt="recommendation-alice-3" width="800"></span></p>
+</div>
+<div class="paragraph">
+<p>This set of products could be the basis for recommendation, but it is important to remember that "alice" may have
+already purchased some of these products and it would be better to not pester her with recommedations for products
+that she already owns. Those products she already purchased can be excluded as follows:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">alice</span><span class="delimiter">'</span></span>).as(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>).
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).aggregate(<span class="string"><span class="delimiter">'</span><span class="content">self</span><span class="delimiter">'</span></span>).
+               in(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).where(neq(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>)).
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).where(without(<span class="string"><span class="delimiter">'</span><span class="content">self</span><span class="delimiter">'</span></span>)).
+               dedup().values(<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>)
+==&gt;product <span class="error">#</span><span class="integer">1</span>
+==&gt;product <span class="error">#</span><span class="integer">2</span>
+==&gt;product <span class="error">#</span><span class="integer">9</span>
+==&gt;product <span class="error">#</span><span class="integer">8</span>
+==&gt;product <span class="error">#</span><span class="integer">10</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p><span class="image"><img src="../images/recommendation-alice-4.png" alt="recommendation-alice-4" width="800"></span></p>
+</div>
+<div class="paragraph">
+<p>The final step would be to group the remaining products (instead of <code>dedup()</code> which was mostly done for demonstration
+purposes) to form a ranking:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">'</span><span class="content">person</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">name</span><span class="delimiter">'</span></span>,<span class="string"><span class="delimiter">'</span><span class="content">alice</span><span class="delimiter">'</span></span>).as(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>). <span class="comment">//</span><b>(1)</b>
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).aggregate(<span class="string"><span class="delimiter">'</span><span class="content">self</span><span class="delimiter">'</span></span>). <span class="comment">//</span><b>(2)</b>
+               <span class="keyword">in</span>(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).where(neq(<span class="string"><span class="delimiter">'</span><span class="content">her</span><span class="delimiter">'</span></span>)). <span class="comment">//</span><b>(3)</b>
+               out(<span class="string"><span class="delimiter">'</span><span class="content">bought</span><span class="delimiter">'</span></span>).where(without(<span class="string"><span class="delimiter">'</span><span class="content">self</span><span class="delimiter">'</span></span>)). <span class="comment">//</span><b>(4)</b>
+               groupCount().order(local).by(values, decr) <span class="comment">//</span><b>(5)</b>
+==&gt;[v[<span class="integer">10</span>]:<span class="integer">6</span>,v[<span class="integer">26</span>]:<span class="integer">5</span>,v[<span class="integer">12</span>]:<span class="integer">5</span>,v[<span class="integer">24</span>]:<span class="integer">4</span>,v[<span class="integer">28</span>]:<span class="integer">2</span>]</code></pre>
+</div>
+</div>
+<div class="colist arabic">
+<ol>
+<li>
+<p>Find "alice" who is the person for whom the product recommendation is being made.</p>
+</li>
+<li>
+<p>Traverse to the products that "alice" bought and gather them for later use in the traversal.</p>
+</li>
+<li>
+<p>Traverse to the "person" vertices who bought the products that "alice" bought and exclude "alice" herself from that list.</p>
+</li>
+<li>
+<p>Given those people who bought similar products to "alice", find the products that they bought and exclude those that she already bought.</p>
+</li>
+<li>
+<p>Group the products and count the number of times they were purchased by others to come up with a ranking of products to recommend to "alice".</p>
+</li>
+</ol>
+</div>
+<div class="paragraph">
+<p>The previous example was already described as "basic" and obviously could take into account whatever data is available
+to further improve the quality of the recommendation (e.g. product ratings, times of purchase, etc.).  One option to
+improve the quality of what is recommended (without expanding the previous dataset) might be to choose the person
+vertices that make up the recommendation to "alice" who have the largest common set of purchases.</p>
+</div>
+<div class="paragraph">
+<p>Looking back to the previous code example, consider its more strip down representation that shows those individuals
+who have at least one product in common:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).aggregate(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>).
+               in(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(neq(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>)).dedup()
+==&gt;v[<span class="integer">2</span>]
+==&gt;v[<span class="integer">6</span>]
+==&gt;v[<span class="integer">8</span>]
+==&gt;v[<span class="integer">4</span>]</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Next, do some grouping to find count how many products they have in common:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).aggregate(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>).
+               in(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(neq(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>)).dedup().
+               group().by().by(out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(within(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>)).count())
+==&gt;[v[<span class="integer">2</span>]:<span class="integer">3</span>,v[<span class="integer">4</span>]:<span class="integer">2</span>,v[<span class="integer">6</span>]:<span class="integer">3</span>,v[<span class="integer">8</span>]:<span class="integer">2</span>]</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The above output shows that the best that can be expected is three common products. The traversal needs to be aware of
+that maximum:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).aggregate(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>).
+               in(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(neq(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>)).dedup().
+               group().by().by(out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).
+                 where(within(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>)).count()).
+               select(values).order(local).by(decr).limit(local, <span class="integer">1</span>)
+==&gt;<span class="integer">3</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>With the maximum value available, it can be used to chose those "person" vertices that have the three products in
+common:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).aggregate(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>).
+               in(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(neq(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>)).dedup().
+               group().by().by(out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).
+                 where(within(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>)).count()).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>).
+               select(values).order(local).by(decr).limit(local, <span class="integer">1</span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>).
+               select(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>).unfold().where(select(values).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>)).select(keys)
+==&gt;v[<span class="integer">2</span>]
+==&gt;v[<span class="integer">6</span>]</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Now that there is a list of "person" vertices to base the recommendation on, traverse to the products that they
+purchased:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).aggregate(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>).
+               in(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(neq(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>)).dedup().
+               group().by().by(out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).
+                 where(within(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>)).count()).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>).
+               select(values).order(local).by(decr).limit(local, <span class="integer">1</span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>).
+               select(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>).unfold().where(select(values).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>)).select(keys).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(without(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>))
+==&gt;v[<span class="integer">10</span>]
+==&gt;v[<span class="integer">10</span>]
+==&gt;v[<span class="integer">12</span>]
+==&gt;v[<span class="integer">26</span>]</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The above output shows that one product is held in common making it the top recommendation:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; g.V().has(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>,<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).aggregate(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>).
+               in(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(neq(<span class="string"><span class="delimiter">&quot;</span><span class="content">alice</span><span class="delimiter">&quot;</span></span>)).dedup().
+               group().by().by(out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).
+                 where(within(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>)).count()).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>).
+               select(values).order(local).by(decr).limit(local, <span class="integer">1</span>).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>).
+               select(<span class="string"><span class="delimiter">&quot;</span><span class="content">g</span><span class="delimiter">&quot;</span></span>).unfold().where(select(values).as(<span class="string"><span class="delimiter">&quot;</span><span class="content">m</span><span class="delimiter">&quot;</span></span>)).select(keys).
+               out(<span class="string"><span class="delimiter">&quot;</span><span class="content">bought</span><span class="delimiter">&quot;</span></span>).where(without(<span class="string"><span class="delimiter">&quot;</span><span class="content">self</span><span class="delimiter">&quot;</span></span>)).
+               groupCount().order(local).by(values, decr).by(select(keys).values(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>)).unfold().select(keys).values(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>)
+==&gt;product <span class="error">#</span><span class="integer">1</span>
+==&gt;product <span class="error">#</span><span class="integer">2</span>
+==&gt;product <span class="error">#</span><span class="integer">9</span></code></pre>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
 <h2 id="shortest-path">Shortest Path</h2>
 <div class="sectionbody">
 <div class="paragraph">
@@ -1542,9 +1833,7 @@ is a simple example that identifies the
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; graph = TinkerGraph.open()
-==&gt;tinkergraph[<span class="key">vertices</span>:<span class="integer">0</span> <span class="key">edges</span>:<span class="integer">0</span>]
-gremlin&gt; v1 = graph.addVertex(T.id, <span class="integer">1</span>)
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; v1 = graph.addVertex(T.id, <span class="integer">1</span>)
 ==&gt;v[<span class="integer">1</span>]
 gremlin&gt; v2 = graph.addVertex(T.id, <span class="integer">2</span>)
 ==&gt;v[<span class="integer">2</span>]
@@ -1601,9 +1890,7 @@ but includes a "weight" on the edges, th
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; graph = TinkerGraph.open()
-==&gt;tinkergraph[<span class="key">vertices</span>:<span class="integer">0</span> <span class="key">edges</span>:<span class="integer">0</span>]
-gremlin&gt; v1 = graph.addVertex(T.id, <span class="integer">1</span>)
+<pre class="CodeRay"><code class="groovy language-groovy">gremlin&gt; v1 = graph.addVertex(T.id, <span class="integer">1</span>)
 ==&gt;v[<span class="integer">1</span>]
 gremlin&gt; v2 = graph.addVertex(T.id, <span class="integer">2</span>)
 ==&gt;v[<span class="integer">2</span>]
@@ -2064,7 +2351,7 @@ submissions!</p>
 </div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2016-10-12 14:45:07 -04:00
+Last updated 2016-10-13 11:25:27 -04:00
 </div>
 </div>
 </body>