<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Fun with ones and zeros - sqlite</title>
<subtitle>Barry&#039;s notes on computer software and hardware</subtitle>
<link href="/blog/tags/sqlite"></link>
<updated>2026-05-03T05:09:14-07:00</updated>
<id>urn:uuid:cdd338d7-f1de-fac8-a172-6e1afbb49f09</id>
<entry>
<title>Full Text Searching with SQLite</title>
<link href="/blog/entries/full-text-searching-sqlite"></link>
<id>urn:uuid:40094c14-09b7-245c-cb8a-1289d723898e</id>
<updated>2006-12-03T16:20:17-08:00</updated>
<author><name>Barry Pederson</name>
<email>bp@barryp.org</email>
</author>
<content type="html">
&lt;p&gt;I&#039;d like to add a search feature back on this site.  Previously, I had an arrangement setup with PyBlosxom and ht://Dig, but now that it&#039;s Django-powered, I&#039;d like to do something that worked directly from the database instead of crawling the site like ht://Dig did.
&lt;/p&gt;
&lt;p&gt;After looking a while at various text search engines, I remembered seeing that &lt;a href=&quot;http://sqlite.org&quot;&gt;SQLite&lt;/a&gt; just added an &lt;a href=&quot;http://www.sqlite.org/cvstrac/wiki?p=FtsOne&quot;&gt;FTS1&lt;/a&gt; module in version 3.3.8, which sounds pretty easy to use.  Unfortunately the FreeBSD port &lt;code&gt;databases/sqlite3&lt;/code&gt; doesn&#039;t build with that feature.
&lt;/p&gt;
&lt;p&gt;After poking around a bit, I got it to build with FTS manually, and after a whole bunch more messing around, came up with a patch to add an option to the port to build sqlite3 with FTS.   The patch has been submitted to the FreeBSD bug tracker as &lt;a href=&quot;http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/106281&quot;&gt;ports/106281&lt;/a&gt;.  Hopefully I have all my ducks lined up on that.
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Anyhow, in testing the FTS a bit, I found one thing they only hint at on the SQLite website.  There&#039;s a &lt;a href=&quot;http://www.tartarus.org/~martin/PorterStemmer/index.html&quot;&gt;Porter stemmer&lt;/a&gt; built in, even though the wiki says: &amp;quot;The module does not perform stemming of any sort.&amp;quot;  You activate it by adding &lt;code&gt;tokenize porter&lt;/code&gt; to the table declaration, for example (adapted from their example).
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VIRTUAL&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;USING&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FTS1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ingredients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;porter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;once you&#039;ve done that, and inserted some sample data:
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;VALUES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;broccoli stew&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;broccoli peppers cheese tomatoes&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;the searches don&#039;t have to be quite as exact, for example:
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ingredients&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;MATCH&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;pepper&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;hits the &#039;broccoli stew&#039; recipe even through it has &#039;peppers&#039; and you searched for &#039;pepper&#039;.
&lt;/p&gt;
&lt;p&gt;Not sure why the Porter stemmer isn&#039;t documented in the SQLite wiki, perhaps it&#039;s still a work in progress or being changed for &lt;a href=&quot;http://www.sqlite.org/cvstrac/wiki?p=FtsTwo&quot;&gt;FTS2&lt;/a&gt;.
&lt;/p&gt;
</content>
</entry>
</feed>