]> granicus.if.org Git - postgresql/blob - doc/src/sgml/pgtrgm.sgml
Ensure that all <sect1> and <refentry> tags have IDs. This is needed
[postgresql] / doc / src / sgml / pgtrgm.sgml
1 <sect1 id="pgtrgm">
2  <title>pg_trgm</title>
3  
4  <indexterm zone="pgtrgm">
5   <primary>pg_trgm</primary>
6  </indexterm>
7
8  <para>
9   The <literal>pg_trgm</literal> module provides functions and index classes
10   for determining the similarity of text based on trigram matching.
11  </para>
12
13  <sect2>
14   <title>Trigram (or Trigraph)</title>
15   <para>
16    A trigram is a set of three consecutive characters taken
17    from a string.  A string is considered to have two spaces
18    prefixed and one space suffixed when determining the set
19    of trigrams that comprise the string.
20   </para>
21   <para>
22    eg. The set of trigrams in the word "cat" is "  c", " ca", 
23    "at " and "cat".
24   </para>
25  </sect2>
26
27  <sect2>
28   <title>Public Functions</title>
29   <table>
30    <title><literal>pg_trgm</literal> functions</title>
31    <tgroup cols="2">
32     <thead>
33      <row>
34       <entry>Function</entry>
35       <entry>Description</entry>
36      </row>
37     </thead>
38     <tbody>
39      <row>
40       <entry><literal>real similarity(text, text)</literal></entry>
41       <entry>
42        <para>
43         Returns a number that indicates how closely matches the two
44         arguments are.  A zero result indicates that the two words
45         are completely dissimilar, and a result of one indicates that
46         the two words are identical.
47        </para>
48       </entry>
49      </row>
50      <row>
51       <entry><literal>real show_limit()</literal></entry>
52       <entry>
53        <para>
54         Returns the current similarity threshold used by the '%'
55         operator.  This in effect sets the minimum similarity between
56         two words in order that they be considered similar enough to
57         be misspellings of each other, for example.
58        </para>
59       </entry>
60      </row>
61      <row>
62       <entry><literal>real set_limit(real)</literal></entry>
63       <entry>
64        <para>
65         Sets the current similarity threshold that is used by the '%'
66         operator, and is returned by the show_limit() function.
67        </para>
68       </entry>
69      </row>
70      <row>
71       <entry><literal>text[] show_trgm(text)</literal></entry>
72       <entry>
73        <para>
74         Returns an array of all the trigrams of the supplied text
75         parameter.
76        </para>
77       </entry>
78      </row>
79      <row>
80       <entry>Operator: <literal>text % text (returns boolean)</literal></entry> 
81       <entry>
82        <para>
83         The '%' operator returns TRUE if its two arguments have a similarity
84         that is greater than the similarity threshold set by set_limit(). It
85         will return FALSE if the similarity is less than the current
86         threshold.
87        </para>
88       </entry>
89      </row>
90     </tbody>
91    </tgroup>
92   </table>
93  </sect2>
94
95  <sect2>
96   <title>Public Index Operator Class</title>
97   <para>
98    The <literal>pg_trgm</literal> module comes with the 
99    <literal>gist_trgm_ops</literal> index operator class that allows a
100    developer to create an index over a text column for the purpose
101    of very fast similarity searches.
102   </para>
103   <para>
104    To use this index, the '%' operator must be used and an appropriate
105    similarity threshold for the application must be set. Example:
106   </para>
107   <programlisting>
108 CREATE TABLE test_trgm (t text);
109 CREATE INDEX trgm_idx ON test_trgm USING gist (t gist_trgm_ops);
110   </programlisting>
111   <para>
112    At this point, you will have an index on the t text column that you
113    can use for similarity searching. Example:
114   </para>
115   <programlisting>
116 SELECT
117         t,
118         similarity(t, 'word') AS sml
119 FROM
120         test_trgm
121 WHERE
122         t % 'word'
123 ORDER BY
124         sml DESC, t;
125   </programlisting>
126   <para>
127    This will return all values in the text column that are sufficiently
128    similar to 'word', sorted from best match to worst.  The index will
129    be used to make this a fast operation over very large data sets.
130   </para>
131  </sect2>
132
133  <sect2>
134   <title>Text Search Integration</title>
135   <para>
136    Trigram matching is a very useful tool when used in conjunction
137    with a full text index.
138   </para>
139   <para>
140    The first step is to generate an auxiliary table containing all
141    the unique words in the documents:
142   </para>
143   <programlisting>
144 CREATE TABLE words AS SELECT word FROM 
145         stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
146   </programlisting>
147   <para>
148    where <structname>documents</> is a table that has a text field
149    <structfield>bodytext</> that we wish to search.  The use of the
150    <literal>simple</> configuration with the <function>to_tsvector</>
151    function, instead of just using the already
152    existing vector is to avoid creating a list of already stemmed
153    words.  This way, only the original, unstemmed words are added
154    to the word list.
155   </para>
156   <para>
157    Next, create a trigram index on the word column:
158   </para>
159   <programlisting>
160 CREATE INDEX words_idx ON words USING gist(word gist_trgm_ops);
161   </programlisting>
162   <para>
163    or
164   </para>
165   <programlisting>
166 CREATE INDEX words_idx ON words USING gin(word gist_trgm_ops);
167   </programlisting>
168   <para>
169    Now, a <literal>SELECT</literal> query similar to the example above can be 
170    used to suggest spellings for misspelled words in user search terms. A
171    useful extra clause is to ensure that the similar words are also
172    of similar length to the misspelled word.
173   </para>
174   <para>
175    <note>
176     <para>
177      Since the <structname>words</> table has been generated as a separate,
178      static table, it will need to be periodically regenerated so that
179      it remains up to date with the document collection.
180     </para>
181    </note>
182   </para>
183  </sect2>
184
185  <sect2>
186   <title>References</title>
187   <para>
188    GiST Development Site
189    <ulink url="http://www.sai.msu.su/~megera/postgres/gist/"></ulink>
190   </para>
191   <para>
192    Tsearch2 Development Site
193    <ulink url="http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/"></ulink>
194   </para>
195  </sect2>
196
197  <sect2>
198   <title>Authors</title>
199   <para>
200    Oleg Bartunov <email>oleg@sai.msu.su</email>, Moscow, Moscow University, Russia
201   </para>
202   <para>
203    Teodor Sigaev <email>teodor@sigaev.ru</email>, Moscow, Delta-Soft Ltd.,Russia
204   </para>
205   <para>
206    Documentation: Christopher Kings-Lynne 
207   </para>
208   <para>
209    This module is sponsored by Delta-Soft Ltd., Moscow, Russia.
210   </para>
211  </sect2>
212
213 </sect1>