blob: d745ea643c9bfe11ddef946227f336aa2c9db237 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<title>Cassandra adapter</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Jekyll v4.2.2">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic,900">
<link rel="stylesheet" href="/css/screen.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body class="wrap">
<header role="banner">
<div class="grid">
<div class="unit center-on-mobiles">
<h1>
<a href="/">
<span class="sr-only">Apache Calcite</span>
<img src="/img/logo.svg" alt="Calcite Logo">
</a>
</h1>
</div>
<nav class="main-nav">
<ul>
<li class="">
<a href="/">Home</a>
</li>
<li class="">
<a href="/downloads/">Download</a>
</li>
<li class="">
<a href="/community/">Community</a>
</li>
<li class="">
<a href="/develop/">Develop</a>
</li>
<li class="">
<a href="/news/">News</a>
</li>
<li class="current">
<a href="/docs/">Docs</a>
</li>
</ul>
</nav>
</div>
</header>
<section class="docs">
<div class="grid">
<div class="docs-nav-mobile unit whole show-on-mobiles">
<select onchange="if (this.value) window.location.href=this.value">
<option value="">Navigate the docs…</option>
<optgroup label="Overview">
</optgroup>
<optgroup label="Advanced">
</optgroup>
<optgroup label="Avatica">
</optgroup>
<optgroup label="Reference">
</optgroup>
<optgroup label="Meta">
</optgroup>
</select>
</div>
<div class="unit four-fifths">
<article>
<h1>Cassandra adapter</h1>
<!--
-->
<p>For instructions on downloading and building Calcite, start with the
<a href="/docs/tutorial.html">tutorial</a>.</p>
<p>Once you’ve managed to compile the project, you can return here to
start querying Cassandra with Calcite. First, we need a
<a href="/docs/model.html">model definition</a>.
The model gives Calcite the necessary parameters to create an instance
of the Cassandra adapter. Note that while models can contain
definitions of
<a href="/docs/model.html#materialization">materializations</a>,
the adapter will attempt to automatically populate any materialized views
<a href="https://www.datastax.com/dev/blog/new-in-cassandra-3-0-materialized-views">defined in Cassandra</a>.</p>
<p>A basic example of a model file is given below:</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="err">version:</span><span class="w"> </span><span class="err">'</span><span class="mf">1.0</span><span class="err">'</span><span class="p">,</span><span class="w">
</span><span class="err">defaultSchema:</span><span class="w"> </span><span class="err">'twissandra'</span><span class="p">,</span><span class="w">
</span><span class="err">schemas:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="err">name:</span><span class="w"> </span><span class="err">'twissandra'</span><span class="p">,</span><span class="w">
</span><span class="err">type:</span><span class="w"> </span><span class="err">'custom'</span><span class="p">,</span><span class="w">
</span><span class="err">factory:</span><span class="w"> </span><span class="err">'org.apache.calcite.adapter.cassandra.CassandraSchemaFactory'</span><span class="p">,</span><span class="w">
</span><span class="err">operand:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="err">host:</span><span class="w"> </span><span class="err">'localhost'</span><span class="p">,</span><span class="w">
</span><span class="err">keyspace:</span><span class="w"> </span><span class="err">'twissandra'</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<p>Note that you can also specify <code class="language-plaintext highlighter-rouge">username</code> and <code class="language-plaintext highlighter-rouge">password</code> keys along with
the <code class="language-plaintext highlighter-rouge">host</code> and <code class="language-plaintext highlighter-rouge">keyspace</code> if your server requires authentication.
Assuming this file is stored as <code class="language-plaintext highlighter-rouge">model.json</code>, you can connect to
Cassandra via <a href="https://github.com/julianhyde/sqlline"><code class="language-plaintext highlighter-rouge">sqlline</code></a> as
follows:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>./sqlline
sqlline&gt; <span class="o">!</span>connect jdbc:calcite:model<span class="o">=</span>model.json admin admin</code></pre></figure>
<p><code class="language-plaintext highlighter-rouge">sqlline</code> will now accept SQL queries which access your CQL tables.
However, you’re not restricted to issuing queries supported by
<a href="https://cassandra.apache.org/doc/cql3/CQL-2.2.html">CQL</a>.
Calcite allows you to perform complex operations such as aggregations
or joins. The adapter will attempt to compile the query into the most
efficient CQL possible by exploiting filtering and sorting directly in
Cassandra where possible.</p>
<p>For example, in the example dataset there is a CQL table named <code class="language-plaintext highlighter-rouge">timeline</code>
with <code class="language-plaintext highlighter-rouge">username</code> as the partition key and <code class="language-plaintext highlighter-rouge">time</code> as the clustering key.</p>
<p>We can issue a simple query to fetch the most recent tweet ID of the
user by writing standard SQL:</p>
<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="n">sqlline</span><span class="o">&gt;</span> <span class="k">SELECT</span> <span class="nv">"tweet_id"</span>
<span class="k">FROM</span> <span class="nv">"timeline"</span>
<span class="k">WHERE</span> <span class="nv">"username"</span> <span class="o">=</span> <span class="s1">'JmuhsAaMdw'</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="nv">"time"</span> <span class="k">DESC</span> <span class="k">LIMIT</span> <span class="mi">1</span><span class="p">;</span>
<span class="o">+</span><span class="c1">--------------------------------------+</span>
<span class="o">|</span> <span class="n">tweet_id</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">--------------------------------------+</span>
<span class="o">|</span> <span class="n">f3d3d4dc</span><span class="o">-</span><span class="n">d05b</span><span class="o">-</span><span class="mi">11</span><span class="n">e5</span><span class="o">-</span><span class="n">b58b</span><span class="o">-</span><span class="mi">90</span><span class="n">e2ba530b12</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">--------------------------------------+</span></code></pre></figure>
<p>While executing this query, the Cassandra adapter is able to recognize
that <code class="language-plaintext highlighter-rouge">username</code> is the partition key and can be filtered by Cassandra.
It also recognizes the clustering key <code class="language-plaintext highlighter-rouge">time</code> and pushes the ordering to
Cassandra as well.</p>
<p>The final CQL query given to Cassandra is below:</p>
<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">SELECT</span> <span class="n">username</span><span class="p">,</span> <span class="nb">time</span><span class="p">,</span> <span class="n">tweet_id</span>
<span class="k">FROM</span> <span class="nv">"timeline"</span>
<span class="k">WHERE</span> <span class="n">username</span> <span class="o">=</span> <span class="s1">'JmuhsAaMdw'</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="nb">time</span> <span class="k">DESC</span> <span class="n">ALLOW</span> <span class="n">FILTERING</span><span class="p">;</span></code></pre></figure>
<p>There is still significant work to do in improving the flexibility and
performance of the adapter, but if you’re looking for a quick way to
gain additional insights into data stored in Cassandra, Calcite should
prove useful.</p>
</article>
</div>
<div class="unit one-fifth hide-on-mobiles">
<aside>
<h4>Overview</h4>
<ul>
<li class=""><a href="/docs/index.html">Background</a></li>
<li class=""><a href="/docs/tutorial.html">Tutorial</a></li>
<li class=""><a href="/docs/algebra.html">Algebra</a></li>
</ul>
<h4>Advanced</h4>
<ul>
<li class=""><a href="/docs/adapter.html">Adapters</a></li>
<li class=""><a href="/docs/spatial.html">Spatial</a></li>
<li class=""><a href="/docs/stream.html">Streaming</a></li>
<li class=""><a href="/docs/materialized_views.html">Materialized Views</a></li>
<li class=""><a href="/docs/lattice.html">Lattices</a></li>
</ul>
<h4>Avatica</h4>
<ul>
<li class=""><a href="/docs/avatica_overview.html">Overview</a></li>
<li class=""><a href="/docs/avatica_roadmap.html">Roadmap</a></li>
<li class=""><a href="/docs/avatica_json_reference.html">JSON Reference</a></li>
<li class=""><a href="/docs/avatica_protobuf_reference.html">Protobuf Reference</a></li>
</ul>
<h4>Reference</h4>
<ul>
<li class=""><a href="/docs/reference.html">SQL language</a></li>
<li class=""><a href="/docs/model.html">JSON/YAML models</a></li>
<li class=""><a href="/docs/howto.html">HOWTO</a></li>
</ul>
<h4>Meta</h4>
<ul>
<li class=""><a href="/docs/history.html">History</a></li>
<li class=""><a href="/docs/powered_by.html">Powered by Calcite</a></li>
<li class=""><a href="/javadocAggregate">API</a></li>
</ul>
</aside>
</div>
<div class="clear"></div>
</div>
</section>
<footer role="contentinfo">
<div id="poweredby">
<a href="http://www.apache.org/">
<span class="sr-only">Apache</span>
<img src="/img/feather.png" width="190" height="77" alt="Apache Logo"></a>
</div>
<div id="copyright">
<p>The contents of this website are Copyright © 2023
<a href="https://www.apache.org/">Apache Software Foundation</a>
under the terms of
the <a href="https://www.apache.org/licenses/">
Apache License v2</a>. Apache Calcite and its logo are
trademarks of the Apache Software Foundation.
</p>
<p>
<a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy Policy</a>
</p>
</div>
</footer>
<script>
var anchorForId = function (id) {
var anchor = document.createElement("a");
anchor.className = "header-link";
anchor.href = "#" + id;
anchor.innerHTML = "<span class=\"sr-only\">Permalink</span><i class=\"fa fa-link\"></i>";
anchor.title = "Permalink";
return anchor;
};
var linkifyAnchors = function (level, containingElement) {
var headers = containingElement.getElementsByTagName("h" + level);
for (var h = 0; h < headers.length; h++) {
var header = headers[h];
if (typeof header.id !== "undefined" && header.id !== "") {
header.appendChild(anchorForId(header.id));
}
}
};
document.onreadystatechange = function () {
if (this.readyState === "complete") {
var contentBlock = document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
if (!contentBlock) {
return;
}
for (var level = 1; level <= 6; level++) {
linkifyAnchors(level, contentBlock);
}
}
};
</script>
</body>
</html>