gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

661 line
36KB

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.6. Dictionaries</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="textsearch-parsers.html" title="12.5. Parsers" /><link rel="next" href="textsearch-configuration.html" title="12.7. Configuration Example" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.6. Dictionaries</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-parsers.html" title="12.5. Parsers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-configuration.html" title="12.7. Configuration Example">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="TEXTSEARCH-DICTIONARIES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.6. Dictionaries</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS">12.6.1. Stop Words</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY">12.6.2. Simple Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SYNONYM-DICTIONARY">12.6.3. Synonym Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-THESAURUS">12.6.4. Thesaurus Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-ISPELL-DICTIONARY">12.6.5. <span class="application">Ispell</span> Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SNOWBALL-DICTIONARY">12.6.6. <span class="application">Snowball</span> Dictionary</a></span></dt></dl></div><p>
  3. Dictionaries are used to eliminate words that should not be considered in a
  4. search (<em class="firstterm">stop words</em>), and to <em class="firstterm">normalize</em> words so
  5. that different derived forms of the same word will match. A successfully
  6. normalized word is called a <em class="firstterm">lexeme</em>. Aside from
  7. improving search quality, normalization and removal of stop words reduce the
  8. size of the <code class="type">tsvector</code> representation of a document, thereby
  9. improving performance. Normalization does not always have linguistic meaning
  10. and usually depends on application semantics.
  11. </p><p>
  12. Some examples of normalization:
  13. </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
  14. Linguistic - Ispell dictionaries try to reduce input words to a
  15. normalized form; stemmer dictionaries remove word endings
  16. </p></li><li class="listitem" style="list-style-type: disc"><p>
  17. <acronym class="acronym">URL</acronym> locations can be canonicalized to make
  18. equivalent URLs match:
  19. </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
  20. http://www.pgsql.ru/db/mw/index.html
  21. </p></li><li class="listitem" style="list-style-type: disc"><p>
  22. http://www.pgsql.ru/db/mw/
  23. </p></li><li class="listitem" style="list-style-type: disc"><p>
  24. http://www.pgsql.ru/db/../db/mw/index.html
  25. </p></li></ul></div><p>
  26. </p></li><li class="listitem" style="list-style-type: disc"><p>
  27. Color names can be replaced by their hexadecimal values, e.g.,
  28. <code class="literal">red, green, blue, magenta -&gt; FF0000, 00FF00, 0000FF, FF00FF</code>
  29. </p></li><li class="listitem" style="list-style-type: disc"><p>
  30. If indexing numbers, we can
  31. remove some fractional digits to reduce the range of possible
  32. numbers, so for example <span class="emphasis"><em>3.14</em></span>159265359,
  33. <span class="emphasis"><em>3.14</em></span>15926, <span class="emphasis"><em>3.14</em></span> will be the same
  34. after normalization if only two digits are kept after the decimal point.
  35. </p></li></ul></div><p>
  36. </p><p>
  37. A dictionary is a program that accepts a token as
  38. input and returns:
  39. </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
  40. an array of lexemes if the input token is known to the dictionary
  41. (notice that one token can produce more than one lexeme)
  42. </p></li><li class="listitem" style="list-style-type: disc"><p>
  43. a single lexeme with the <code class="literal">TSL_FILTER</code> flag set, to replace
  44. the original token with a new token to be passed to subsequent
  45. dictionaries (a dictionary that does this is called a
  46. <em class="firstterm">filtering dictionary</em>)
  47. </p></li><li class="listitem" style="list-style-type: disc"><p>
  48. an empty array if the dictionary knows the token, but it is a stop word
  49. </p></li><li class="listitem" style="list-style-type: disc"><p>
  50. <code class="literal">NULL</code> if the dictionary does not recognize the input token
  51. </p></li></ul></div><p>
  52. </p><p>
  53. <span class="productname">PostgreSQL</span> provides predefined dictionaries for
  54. many languages. There are also several predefined templates that can be
  55. used to create new dictionaries with custom parameters. Each predefined
  56. dictionary template is described below. If no existing
  57. template is suitable, it is possible to create new ones; see the
  58. <code class="filename">contrib/</code> area of the <span class="productname">PostgreSQL</span> distribution
  59. for examples.
  60. </p><p>
  61. A text search configuration binds a parser together with a set of
  62. dictionaries to process the parser's output tokens. For each token
  63. type that the parser can return, a separate list of dictionaries is
  64. specified by the configuration. When a token of that type is found
  65. by the parser, each dictionary in the list is consulted in turn,
  66. until some dictionary recognizes it as a known word. If it is identified
  67. as a stop word, or if no dictionary recognizes the token, it will be
  68. discarded and not indexed or searched for.
  69. Normally, the first dictionary that returns a non-<code class="literal">NULL</code>
  70. output determines the result, and any remaining dictionaries are not
  71. consulted; but a filtering dictionary can replace the given word
  72. with a modified word, which is then passed to subsequent dictionaries.
  73. </p><p>
  74. The general rule for configuring a list of dictionaries
  75. is to place first the most narrow, most specific dictionary, then the more
  76. general dictionaries, finishing with a very general dictionary, like
  77. a <span class="application">Snowball</span> stemmer or <code class="literal">simple</code>, which
  78. recognizes everything. For example, for an astronomy-specific search
  79. (<code class="literal">astro_en</code> configuration) one could bind token type
  80. <code class="type">asciiword</code> (ASCII word) to a synonym dictionary of astronomical
  81. terms, a general English dictionary and a <span class="application">Snowball</span> English
  82. stemmer:
  83. </p><pre class="programlisting">
  84. ALTER TEXT SEARCH CONFIGURATION astro_en
  85. ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;
  86. </pre><p>
  87. </p><p>
  88. A filtering dictionary can be placed anywhere in the list, except at the
  89. end where it'd be useless. Filtering dictionaries are useful to partially
  90. normalize words to simplify the task of later dictionaries. For example,
  91. a filtering dictionary could be used to remove accents from accented
  92. letters, as is done by the <a class="xref" href="unaccent.html" title="F.43. unaccent">unaccent</a> module.
  93. </p><div class="sect2" id="TEXTSEARCH-STOPWORDS"><div class="titlepage"><div><div><h3 class="title">12.6.1. Stop Words</h3></div></div></div><p>
  94. Stop words are words that are very common, appear in almost every
  95. document, and have no discrimination value. Therefore, they can be ignored
  96. in the context of full text searching. For example, every English text
  97. contains words like <code class="literal">a</code> and <code class="literal">the</code>, so it is
  98. useless to store them in an index. However, stop words do affect the
  99. positions in <code class="type">tsvector</code>, which in turn affect ranking:
  100. </p><pre class="screen">
  101. SELECT to_tsvector('english','in the list of stop words');
  102. to_tsvector
  103. ----------------------------
  104. 'list':3 'stop':5 'word':6
  105. </pre><p>
  106. The missing positions 1,2,4 are because of stop words. Ranks
  107. calculated for documents with and without stop words are quite different:
  108. </p><pre class="screen">
  109. SELECT ts_rank_cd (to_tsvector('english','in the list of stop words'), to_tsquery('list &amp; stop'));
  110. ts_rank_cd
  111. ------------
  112. 0.05
  113. SELECT ts_rank_cd (to_tsvector('english','list stop words'), to_tsquery('list &amp; stop'));
  114. ts_rank_cd
  115. ------------
  116. 0.1
  117. </pre><p>
  118. </p><p>
  119. It is up to the specific dictionary how it treats stop words. For example,
  120. <code class="literal">ispell</code> dictionaries first normalize words and then
  121. look at the list of stop words, while <code class="literal">Snowball</code> stemmers
  122. first check the list of stop words. The reason for the different
  123. behavior is an attempt to decrease noise.
  124. </p></div><div class="sect2" id="TEXTSEARCH-SIMPLE-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.2. Simple Dictionary</h3></div></div></div><p>
  125. The <code class="literal">simple</code> dictionary template operates by converting the
  126. input token to lower case and checking it against a file of stop words.
  127. If it is found in the file then an empty array is returned, causing
  128. the token to be discarded. If not, the lower-cased form of the word
  129. is returned as the normalized lexeme. Alternatively, the dictionary
  130. can be configured to report non-stop-words as unrecognized, allowing
  131. them to be passed on to the next dictionary in the list.
  132. </p><p>
  133. Here is an example of a dictionary definition using the <code class="literal">simple</code>
  134. template:
  135. </p><pre class="programlisting">
  136. CREATE TEXT SEARCH DICTIONARY public.simple_dict (
  137. TEMPLATE = pg_catalog.simple,
  138. STOPWORDS = english
  139. );
  140. </pre><p>
  141. Here, <code class="literal">english</code> is the base name of a file of stop words.
  142. The file's full name will be
  143. <code class="filename">$SHAREDIR/tsearch_data/english.stop</code>,
  144. where <code class="literal">$SHAREDIR</code> means the
  145. <span class="productname">PostgreSQL</span> installation's shared-data directory,
  146. often <code class="filename">/usr/local/share/postgresql</code> (use <code class="command">pg_config
  147. --sharedir</code> to determine it if you're not sure).
  148. The file format is simply a list
  149. of words, one per line. Blank lines and trailing spaces are ignored,
  150. and upper case is folded to lower case, but no other processing is done
  151. on the file contents.
  152. </p><p>
  153. Now we can test our dictionary:
  154. </p><pre class="screen">
  155. SELECT ts_lexize('public.simple_dict','YeS');
  156. ts_lexize
  157. -----------
  158. {yes}
  159. SELECT ts_lexize('public.simple_dict','The');
  160. ts_lexize
  161. -----------
  162. {}
  163. </pre><p>
  164. </p><p>
  165. We can also choose to return <code class="literal">NULL</code>, instead of the lower-cased
  166. word, if it is not found in the stop words file. This behavior is
  167. selected by setting the dictionary's <code class="literal">Accept</code> parameter to
  168. <code class="literal">false</code>. Continuing the example:
  169. </p><pre class="screen">
  170. ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false );
  171. SELECT ts_lexize('public.simple_dict','YeS');
  172. ts_lexize
  173. -----------
  174. SELECT ts_lexize('public.simple_dict','The');
  175. ts_lexize
  176. -----------
  177. {}
  178. </pre><p>
  179. </p><p>
  180. With the default setting of <code class="literal">Accept</code> = <code class="literal">true</code>,
  181. it is only useful to place a <code class="literal">simple</code> dictionary at the end
  182. of a list of dictionaries, since it will never pass on any token to
  183. a following dictionary. Conversely, <code class="literal">Accept</code> = <code class="literal">false</code>
  184. is only useful when there is at least one following dictionary.
  185. </p><div class="caution"><h3 class="title">Caution</h3><p>
  186. Most types of dictionaries rely on configuration files, such as files of
  187. stop words. These files <span class="emphasis"><em>must</em></span> be stored in UTF-8 encoding.
  188. They will be translated to the actual database encoding, if that is
  189. different, when they are read into the server.
  190. </p></div><div class="caution"><h3 class="title">Caution</h3><p>
  191. Normally, a database session will read a dictionary configuration file
  192. only once, when it is first used within the session. If you modify a
  193. configuration file and want to force existing sessions to pick up the
  194. new contents, issue an <code class="command">ALTER TEXT SEARCH DICTIONARY</code> command
  195. on the dictionary. This can be a <span class="quote">“<span class="quote">dummy</span>”</span> update that doesn't
  196. actually change any parameter values.
  197. </p></div></div><div class="sect2" id="TEXTSEARCH-SYNONYM-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.3. Synonym Dictionary</h3></div></div></div><p>
  198. This dictionary template is used to create dictionaries that replace a
  199. word with a synonym. Phrases are not supported (use the thesaurus
  200. template (<a class="xref" href="textsearch-dictionaries.html#TEXTSEARCH-THESAURUS" title="12.6.4. Thesaurus Dictionary">Section 12.6.4</a>) for that). A synonym
  201. dictionary can be used to overcome linguistic problems, for example, to
  202. prevent an English stemmer dictionary from reducing the word <span class="quote">“<span class="quote">Paris</span>”</span> to
  203. <span class="quote">“<span class="quote">pari</span>”</span>. It is enough to have a <code class="literal">Paris paris</code> line in the
  204. synonym dictionary and put it before the <code class="literal">english_stem</code>
  205. dictionary. For example:
  206. </p><pre class="screen">
  207. SELECT * FROM ts_debug('english', 'Paris');
  208. alias | description | token | dictionaries | dictionary | lexemes
  209. -----------+-----------------+-------+----------------+--------------+---------
  210. asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari}
  211. CREATE TEXT SEARCH DICTIONARY my_synonym (
  212. TEMPLATE = synonym,
  213. SYNONYMS = my_synonyms
  214. );
  215. ALTER TEXT SEARCH CONFIGURATION english
  216. ALTER MAPPING FOR asciiword
  217. WITH my_synonym, english_stem;
  218. SELECT * FROM ts_debug('english', 'Paris');
  219. alias | description | token | dictionaries | dictionary | lexemes
  220. -----------+-----------------+-------+---------------------------+------------+---------
  221. asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris}
  222. </pre><p>
  223. </p><p>
  224. The only parameter required by the <code class="literal">synonym</code> template is
  225. <code class="literal">SYNONYMS</code>, which is the base name of its configuration file
  226. — <code class="literal">my_synonyms</code> in the above example.
  227. The file's full name will be
  228. <code class="filename">$SHAREDIR/tsearch_data/my_synonyms.syn</code>
  229. (where <code class="literal">$SHAREDIR</code> means the
  230. <span class="productname">PostgreSQL</span> installation's shared-data directory).
  231. The file format is just one line
  232. per word to be substituted, with the word followed by its synonym,
  233. separated by white space. Blank lines and trailing spaces are ignored.
  234. </p><p>
  235. The <code class="literal">synonym</code> template also has an optional parameter
  236. <code class="literal">CaseSensitive</code>, which defaults to <code class="literal">false</code>. When
  237. <code class="literal">CaseSensitive</code> is <code class="literal">false</code>, words in the synonym file
  238. are folded to lower case, as are input tokens. When it is
  239. <code class="literal">true</code>, words and tokens are not folded to lower case,
  240. but are compared as-is.
  241. </p><p>
  242. An asterisk (<code class="literal">*</code>) can be placed at the end of a synonym
  243. in the configuration file. This indicates that the synonym is a prefix.
  244. The asterisk is ignored when the entry is used in
  245. <code class="function">to_tsvector()</code>, but when it is used in
  246. <code class="function">to_tsquery()</code>, the result will be a query item with
  247. the prefix match marker (see
  248. <a class="xref" href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES" title="12.3.2. Parsing Queries">Section 12.3.2</a>).
  249. For example, suppose we have these entries in
  250. <code class="filename">$SHAREDIR/tsearch_data/synonym_sample.syn</code>:
  251. </p><pre class="programlisting">
  252. postgres pgsql
  253. postgresql pgsql
  254. postgre pgsql
  255. gogle googl
  256. indices index*
  257. </pre><p>
  258. Then we will get these results:
  259. </p><pre class="screen">
  260. mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample');
  261. mydb=# SELECT ts_lexize('syn','indices');
  262. ts_lexize
  263. -----------
  264. {index}
  265. (1 row)
  266. mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple);
  267. mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn;
  268. mydb=# SELECT to_tsvector('tst','indices');
  269. to_tsvector
  270. -------------
  271. 'index':1
  272. (1 row)
  273. mydb=# SELECT to_tsquery('tst','indices');
  274. to_tsquery
  275. ------------
  276. 'index':*
  277. (1 row)
  278. mydb=# SELECT 'indexes are very useful'::tsvector;
  279. tsvector
  280. ---------------------------------
  281. 'are' 'indexes' 'useful' 'very'
  282. (1 row)
  283. mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst','indices');
  284. ?column?
  285. ----------
  286. t
  287. (1 row)
  288. </pre><p>
  289. </p></div><div class="sect2" id="TEXTSEARCH-THESAURUS"><div class="titlepage"><div><div><h3 class="title">12.6.4. Thesaurus Dictionary</h3></div></div></div><p>
  290. A thesaurus dictionary (sometimes abbreviated as <acronym class="acronym">TZ</acronym>) is
  291. a collection of words that includes information about the relationships
  292. of words and phrases, i.e., broader terms (<acronym class="acronym">BT</acronym>), narrower
  293. terms (<acronym class="acronym">NT</acronym>), preferred terms, non-preferred terms, related
  294. terms, etc.
  295. </p><p>
  296. Basically a thesaurus dictionary replaces all non-preferred terms by one
  297. preferred term and, optionally, preserves the original terms for indexing
  298. as well. <span class="productname">PostgreSQL</span>'s current implementation of the
  299. thesaurus dictionary is an extension of the synonym dictionary with added
  300. <em class="firstterm">phrase</em> support. A thesaurus dictionary requires
  301. a configuration file of the following format:
  302. </p><pre class="programlisting">
  303. # this is a comment
  304. sample word(s) : indexed word(s)
  305. more sample word(s) : more indexed word(s)
  306. ...
  307. </pre><p>
  308. where the colon (<code class="symbol">:</code>) symbol acts as a delimiter between a
  309. phrase and its replacement.
  310. </p><p>
  311. A thesaurus dictionary uses a <em class="firstterm">subdictionary</em> (which
  312. is specified in the dictionary's configuration) to normalize the input
  313. text before checking for phrase matches. It is only possible to select one
  314. subdictionary. An error is reported if the subdictionary fails to
  315. recognize a word. In that case, you should remove the use of the word or
  316. teach the subdictionary about it. You can place an asterisk
  317. (<code class="symbol">*</code>) at the beginning of an indexed word to skip applying
  318. the subdictionary to it, but all sample words <span class="emphasis"><em>must</em></span> be known
  319. to the subdictionary.
  320. </p><p>
  321. The thesaurus dictionary chooses the longest match if there are multiple
  322. phrases matching the input, and ties are broken by using the last
  323. definition.
  324. </p><p>
  325. Specific stop words recognized by the subdictionary cannot be
  326. specified; instead use <code class="literal">?</code> to mark the location where any
  327. stop word can appear. For example, assuming that <code class="literal">a</code> and
  328. <code class="literal">the</code> are stop words according to the subdictionary:
  329. </p><pre class="programlisting">
  330. ? one ? two : swsw
  331. </pre><p>
  332. matches <code class="literal">a one the two</code> and <code class="literal">the one a two</code>;
  333. both would be replaced by <code class="literal">swsw</code>.
  334. </p><p>
  335. Since a thesaurus dictionary has the capability to recognize phrases it
  336. must remember its state and interact with the parser. A thesaurus dictionary
  337. uses these assignments to check if it should handle the next word or stop
  338. accumulation. The thesaurus dictionary must be configured
  339. carefully. For example, if the thesaurus dictionary is assigned to handle
  340. only the <code class="literal">asciiword</code> token, then a thesaurus dictionary
  341. definition like <code class="literal">one 7</code> will not work since token type
  342. <code class="literal">uint</code> is not assigned to the thesaurus dictionary.
  343. </p><div class="caution"><h3 class="title">Caution</h3><p>
  344. Thesauruses are used during indexing so any change in the thesaurus
  345. dictionary's parameters <span class="emphasis"><em>requires</em></span> reindexing.
  346. For most other dictionary types, small changes such as adding or
  347. removing stopwords does not force reindexing.
  348. </p></div><div class="sect3" id="TEXTSEARCH-THESAURUS-CONFIG"><div class="titlepage"><div><div><h4 class="title">12.6.4.1. Thesaurus Configuration</h4></div></div></div><p>
  349. To define a new thesaurus dictionary, use the <code class="literal">thesaurus</code>
  350. template. For example:
  351. </p><pre class="programlisting">
  352. CREATE TEXT SEARCH DICTIONARY thesaurus_simple (
  353. TEMPLATE = thesaurus,
  354. DictFile = mythesaurus,
  355. Dictionary = pg_catalog.english_stem
  356. );
  357. </pre><p>
  358. Here:
  359. </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
  360. <code class="literal">thesaurus_simple</code> is the new dictionary's name
  361. </p></li><li class="listitem" style="list-style-type: disc"><p>
  362. <code class="literal">mythesaurus</code> is the base name of the thesaurus
  363. configuration file.
  364. (Its full name will be <code class="filename">$SHAREDIR/tsearch_data/mythesaurus.ths</code>,
  365. where <code class="literal">$SHAREDIR</code> means the installation shared-data
  366. directory.)
  367. </p></li><li class="listitem" style="list-style-type: disc"><p>
  368. <code class="literal">pg_catalog.english_stem</code> is the subdictionary (here,
  369. a Snowball English stemmer) to use for thesaurus normalization.
  370. Notice that the subdictionary will have its own
  371. configuration (for example, stop words), which is not shown here.
  372. </p></li></ul></div><p>
  373. Now it is possible to bind the thesaurus dictionary <code class="literal">thesaurus_simple</code>
  374. to the desired token types in a configuration, for example:
  375. </p><pre class="programlisting">
  376. ALTER TEXT SEARCH CONFIGURATION russian
  377. ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
  378. WITH thesaurus_simple;
  379. </pre><p>
  380. </p></div><div class="sect3" id="TEXTSEARCH-THESAURUS-EXAMPLES"><div class="titlepage"><div><div><h4 class="title">12.6.4.2. Thesaurus Example</h4></div></div></div><p>
  381. Consider a simple astronomical thesaurus <code class="literal">thesaurus_astro</code>,
  382. which contains some astronomical word combinations:
  383. </p><pre class="programlisting">
  384. supernovae stars : sn
  385. crab nebulae : crab
  386. </pre><p>
  387. Below we create a dictionary and bind some token types to
  388. an astronomical thesaurus and English stemmer:
  389. </p><pre class="programlisting">
  390. CREATE TEXT SEARCH DICTIONARY thesaurus_astro (
  391. TEMPLATE = thesaurus,
  392. DictFile = thesaurus_astro,
  393. Dictionary = english_stem
  394. );
  395. ALTER TEXT SEARCH CONFIGURATION russian
  396. ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
  397. WITH thesaurus_astro, english_stem;
  398. </pre><p>
  399. Now we can see how it works.
  400. <code class="function">ts_lexize</code> is not very useful for testing a thesaurus,
  401. because it treats its input as a single token. Instead we can use
  402. <code class="function">plainto_tsquery</code> and <code class="function">to_tsvector</code>
  403. which will break their input strings into multiple tokens:
  404. </p><pre class="screen">
  405. SELECT plainto_tsquery('supernova star');
  406. plainto_tsquery
  407. -----------------
  408. 'sn'
  409. SELECT to_tsvector('supernova star');
  410. to_tsvector
  411. -------------
  412. 'sn':1
  413. </pre><p>
  414. In principle, one can use <code class="function">to_tsquery</code> if you quote
  415. the argument:
  416. </p><pre class="screen">
  417. SELECT to_tsquery('''supernova star''');
  418. to_tsquery
  419. ------------
  420. 'sn'
  421. </pre><p>
  422. Notice that <code class="literal">supernova star</code> matches <code class="literal">supernovae
  423. stars</code> in <code class="literal">thesaurus_astro</code> because we specified
  424. the <code class="literal">english_stem</code> stemmer in the thesaurus definition.
  425. The stemmer removed the <code class="literal">e</code> and <code class="literal">s</code>.
  426. </p><p>
  427. To index the original phrase as well as the substitute, just include it
  428. in the right-hand part of the definition:
  429. </p><pre class="screen">
  430. supernovae stars : sn supernovae stars
  431. SELECT plainto_tsquery('supernova star');
  432. plainto_tsquery
  433. -----------------------------
  434. 'sn' &amp; 'supernova' &amp; 'star'
  435. </pre><p>
  436. </p></div></div><div class="sect2" id="TEXTSEARCH-ISPELL-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.5. <span class="application">Ispell</span> Dictionary</h3></div></div></div><p>
  437. The <span class="application">Ispell</span> dictionary template supports
  438. <em class="firstterm">morphological dictionaries</em>, which can normalize many
  439. different linguistic forms of a word into the same lexeme. For example,
  440. an English <span class="application">Ispell</span> dictionary can match all declensions and
  441. conjugations of the search term <code class="literal">bank</code>, e.g.,
  442. <code class="literal">banking</code>, <code class="literal">banked</code>, <code class="literal">banks</code>,
  443. <code class="literal">banks'</code>, and <code class="literal">bank's</code>.
  444. </p><p>
  445. The standard <span class="productname">PostgreSQL</span> distribution does
  446. not include any <span class="application">Ispell</span> configuration files.
  447. Dictionaries for a large number of languages are available from <a class="ulink" href="https://www.cs.hmc.edu/~geoff/ispell.html" target="_top">Ispell</a>.
  448. Also, some more modern dictionary file formats are supported — <a class="ulink" href="https://en.wikipedia.org/wiki/MySpell" target="_top">MySpell</a> (OO &lt; 2.0.1)
  449. and <a class="ulink" href="https://sourceforge.net/projects/hunspell/" target="_top">Hunspell</a>
  450. (OO &gt;= 2.0.2). A large list of dictionaries is available on the <a class="ulink" href="https://wiki.openoffice.org/wiki/Dictionaries" target="_top">OpenOffice
  451. Wiki</a>.
  452. </p><p>
  453. To create an <span class="application">Ispell</span> dictionary perform these steps:
  454. </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
  455. download dictionary configuration files. <span class="productname">OpenOffice</span>
  456. extension files have the <code class="filename">.oxt</code> extension. It is necessary
  457. to extract <code class="filename">.aff</code> and <code class="filename">.dic</code> files, change
  458. extensions to <code class="filename">.affix</code> and <code class="filename">.dict</code>. For some
  459. dictionary files it is also needed to convert characters to the UTF-8
  460. encoding with commands (for example, for a Norwegian language dictionary):
  461. </p><pre class="programlisting">
  462. iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff
  463. iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic
  464. </pre><p>
  465. </p></li><li class="listitem" style="list-style-type: disc"><p>
  466. copy files to the <code class="filename">$SHAREDIR/tsearch_data</code> directory
  467. </p></li><li class="listitem" style="list-style-type: disc"><p>
  468. load files into PostgreSQL with the following command:
  469. </p><pre class="programlisting">
  470. CREATE TEXT SEARCH DICTIONARY english_hunspell (
  471. TEMPLATE = ispell,
  472. DictFile = en_us,
  473. AffFile = en_us,
  474. Stopwords = english);
  475. </pre><p>
  476. </p></li></ul></div><p>
  477. Here, <code class="literal">DictFile</code>, <code class="literal">AffFile</code>, and <code class="literal">StopWords</code>
  478. specify the base names of the dictionary, affixes, and stop-words files.
  479. The stop-words file has the same format explained above for the
  480. <code class="literal">simple</code> dictionary type. The format of the other files is
  481. not specified here but is available from the above-mentioned web sites.
  482. </p><p>
  483. Ispell dictionaries usually recognize a limited set of words, so they
  484. should be followed by another broader dictionary; for
  485. example, a Snowball dictionary, which recognizes everything.
  486. </p><p>
  487. The <code class="filename">.affix</code> file of <span class="application">Ispell</span> has the following
  488. structure:
  489. </p><pre class="programlisting">
  490. prefixes
  491. flag *A:
  492. . &gt; RE # As in enter &gt; reenter
  493. suffixes
  494. flag T:
  495. E &gt; ST # As in late &gt; latest
  496. [^AEIOU]Y &gt; -Y,IEST # As in dirty &gt; dirtiest
  497. [AEIOU]Y &gt; EST # As in gray &gt; grayest
  498. [^EY] &gt; EST # As in small &gt; smallest
  499. </pre><p>
  500. </p><p>
  501. And the <code class="filename">.dict</code> file has the following structure:
  502. </p><pre class="programlisting">
  503. lapse/ADGRS
  504. lard/DGRS
  505. large/PRTY
  506. lark/MRS
  507. </pre><p>
  508. </p><p>
  509. Format of the <code class="filename">.dict</code> file is:
  510. </p><pre class="programlisting">
  511. basic_form/affix_class_name
  512. </pre><p>
  513. </p><p>
  514. In the <code class="filename">.affix</code> file every affix flag is described in the
  515. following format:
  516. </p><pre class="programlisting">
  517. condition &gt; [-stripping_letters,] adding_affix
  518. </pre><p>
  519. </p><p>
  520. Here, condition has a format similar to the format of regular expressions.
  521. It can use groupings <code class="literal">[...]</code> and <code class="literal">[^...]</code>.
  522. For example, <code class="literal">[AEIOU]Y</code> means that the last letter of the word
  523. is <code class="literal">"y"</code> and the penultimate letter is <code class="literal">"a"</code>,
  524. <code class="literal">"e"</code>, <code class="literal">"i"</code>, <code class="literal">"o"</code> or <code class="literal">"u"</code>.
  525. <code class="literal">[^EY]</code> means that the last letter is neither <code class="literal">"e"</code>
  526. nor <code class="literal">"y"</code>.
  527. </p><p>
  528. Ispell dictionaries support splitting compound words;
  529. a useful feature.
  530. Notice that the affix file should specify a special flag using the
  531. <code class="literal">compoundwords controlled</code> statement that marks dictionary
  532. words that can participate in compound formation:
  533. </p><pre class="programlisting">
  534. compoundwords controlled z
  535. </pre><p>
  536. Here are some examples for the Norwegian language:
  537. </p><pre class="programlisting">
  538. SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
  539. {over,buljong,terning,pakk,mester,assistent}
  540. SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
  541. {sjokoladefabrikk,sjokolade,fabrikk}
  542. </pre><p>
  543. </p><p>
  544. <span class="application">MySpell</span> format is a subset of <span class="application">Hunspell</span>.
  545. The <code class="filename">.affix</code> file of <span class="application">Hunspell</span> has the following
  546. structure:
  547. </p><pre class="programlisting">
  548. PFX A Y 1
  549. PFX A 0 re .
  550. SFX T N 4
  551. SFX T 0 st e
  552. SFX T y iest [^aeiou]y
  553. SFX T 0 est [aeiou]y
  554. SFX T 0 est [^ey]
  555. </pre><p>
  556. </p><p>
  557. The first line of an affix class is the header. Fields of an affix rules are
  558. listed after the header:
  559. </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
  560. parameter name (PFX or SFX)
  561. </p></li><li class="listitem" style="list-style-type: disc"><p>
  562. flag (name of the affix class)
  563. </p></li><li class="listitem" style="list-style-type: disc"><p>
  564. stripping characters from beginning (at prefix) or end (at suffix) of the
  565. word
  566. </p></li><li class="listitem" style="list-style-type: disc"><p>
  567. adding affix
  568. </p></li><li class="listitem" style="list-style-type: disc"><p>
  569. condition that has a format similar to the format of regular expressions.
  570. </p></li></ul></div><p>
  571. The <code class="filename">.dict</code> file looks like the <code class="filename">.dict</code> file of
  572. <span class="application">Ispell</span>:
  573. </p><pre class="programlisting">
  574. larder/M
  575. lardy/RT
  576. large/RSPMYT
  577. largehearted
  578. </pre><p>
  579. </p><div class="note"><h3 class="title">Note</h3><p>
  580. <span class="application">MySpell</span> does not support compound words.
  581. <span class="application">Hunspell</span> has sophisticated support for compound words. At
  582. present, <span class="productname">PostgreSQL</span> implements only the basic
  583. compound word operations of Hunspell.
  584. </p></div></div><div class="sect2" id="TEXTSEARCH-SNOWBALL-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.6. <span class="application">Snowball</span> Dictionary</h3></div></div></div><p>
  585. The <span class="application">Snowball</span> dictionary template is based on a project
  586. by Martin Porter, inventor of the popular Porter's stemming algorithm
  587. for the English language. Snowball now provides stemming algorithms for
  588. many languages (see the <a class="ulink" href="https://snowballstem.org/" target="_top">Snowball
  589. site</a> for more information). Each algorithm understands how to
  590. reduce common variant forms of words to a base, or stem, spelling within
  591. its language. A Snowball dictionary requires a <code class="literal">language</code>
  592. parameter to identify which stemmer to use, and optionally can specify a
  593. <code class="literal">stopword</code> file name that gives a list of words to eliminate.
  594. (<span class="productname">PostgreSQL</span>'s standard stopword lists are also
  595. provided by the Snowball project.)
  596. For example, there is a built-in definition equivalent to
  597. </p><pre class="programlisting">
  598. CREATE TEXT SEARCH DICTIONARY english_stem (
  599. TEMPLATE = snowball,
  600. Language = english,
  601. StopWords = english
  602. );
  603. </pre><p>
  604. The stopword file format is the same as already explained.
  605. </p><p>
  606. A <span class="application">Snowball</span> dictionary recognizes everything, whether
  607. or not it is able to simplify the word, so it should be placed
  608. at the end of the dictionary list. It is useless to have it
  609. before any other dictionary because a token will never pass through it to
  610. the next dictionary.
  611. </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-parsers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-configuration.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.5. Parsers </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 12.7. Configuration Example</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1