# 12.6.字典

12.6.1. 停止说话

12.6.2. 简单词典

12.6.3. 同义词词典

12.6.4. 同义词词典

12.6.5. 伊斯佩尔词典

12.6.6. 雪球词典

字典用于删除搜索中不应考虑的单词(停止说话),以及规范化使同一单词的不同派生形式匹配。成功规范化的单词称为词素.除了提高搜索质量外,规范化和删除停止词还可以缩小搜索范围tsvector表示文档,从而提高性能。规范化并不总是具有语言意义,通常取决于应用程序语义。

标准化的一些例子:

  • 语言学——Ispell词典试图将输入词简化为规范化形式;词干分析器词典删除词尾

  • URL位置可以规范化,以使等效URL匹配:

  • 颜色名称可以替换为其十六进制值,例如:。,红、绿、蓝、洋红->FF0000、00FF00、0000FF、FF00FF

  • 如果索引数字,我们可以删除一些小数位数以减少可能的数字范围,例如3.14159265359,3.1415926, 3.14如果小数点后只保留两位数字,则标准化后将保持相同。

    字典是一个程序,它接受令牌作为输入并返回:

  • 一个词素数组,如果字典知道输入标记(请注意,一个标记可以产生多个词素)

  • 带有TSL_滤波器标志集,将原始标记替换为新标记,并传递给后续字典(执行此操作的字典称为过滤字典)

  • 如果字典知道标记,但它是停止词,则为空数组

  • 无效的如果字典无法识别输入标记

PostgreSQL为多种语言提供预定义的词典。还有几个预定义的模板可用于创建带有自定义参数的新词典。下面介绍每个预定义的字典模板。如果没有合适的现有模板,可以创建新模板;看到了吗contrib/例如,PostgreSQL发行版的区域。

文本搜索配置将解析器与一组字典绑定在一起,以处理解析器的输出标记。对于解析器可以返回的每个令牌类型,配置会指定一个单独的字典列表。当解析器找到该类型的标记时,会依次查阅列表中的每个字典,直到某个字典将其识别为已知单词。如果它被识别为停止词,或者如果没有字典识别该标记,它将被丢弃,并且不会被索引或搜索。通常,第一个返回非-无效的输出决定结果,不查阅任何剩余的词典;但是过滤字典可以用修改过的单词替换给定的单词,然后将其传递给后续字典。

配置字典列表的一般规则是,首先放置最窄、最具体的字典,然后是更一般的字典,最后是非常一般的字典,如雪球词干分析器或易于理解的,它能识别一切。例如,对于特定于天文学的搜索(阿斯特罗恩配置)可以绑定令牌类型阿西沃德(ASCII单词)到天文术语同义词词典、通用英语词典和雪球英语词干分析器:

ALTER TEXT SEARCH CONFIGURATION astro_en
    ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;

过滤字典可以放在列表中的任何位置,除非放在末尾,否则它就没用了。过滤词典有助于部分规范化单词,以简化后续词典的任务。例如,过滤字典可以用来删除重音字母中的重音,就像不合适的单元

# 12.6.1.停止说话

停止词是非常常见的词,几乎出现在每个文档中,并且没有区别价值。因此,在全文搜索中可以忽略它们。例如,每个英文文本都包含以下单词A.这个,因此将它们存储在索引中是无用的。然而,停止语确实会影响到句子中的位置tsvector,进而影响排名:

SELECT to_tsvector('english', 'in the list of stop words');
        to_tsvector
### 12.6.2. Simple Dictionary

 The `simple` dictionary template operates by converting the input token to lower case and checking it against a file of stop words. If it is found in the file then an empty array is returned, causing the token to be discarded. If not, the lower-cased form of the word is returned as the normalized lexeme. Alternatively, the dictionary can be configured to report non-stop-words as unrecognized, allowing them to be passed on to the next dictionary in the list.

 Here is an example of a dictionary definition using the `simple` template:

创建文本搜索词典。simple_dict(TEMPLATE=pg_catalog.simple,STOPWORDS=english);

 Here, `english` is the base name of a file of stop words. The file's full name will be `$SHAREDIR/tsearch_data/english.stop`, where `$SHAREDIR` means the PostgreSQL installation's shared-data directory, often `/usr/local/share/postgresql` (use `pg_config --sharedir` to determine it if you're not sure). The file format is simply a list of words, one per line. Blank lines and trailing spaces are ignored, and upper case is folded to lower case, but no other processing is done on the file contents.

 Now we can test our dictionary:

选择ts_lexize('public.simple_dict','YeS');ts_lexize

# 小心

大多数类型的词典都依赖于配置文件,例如停止词文件。这些文件必须以UTF-8编码存储。当它们被读入服务器时,它们将被转换为实际的数据库编码(如果不同的话)。

# 小心

通常,数据库会话在会话中首次使用字典配置文件时,只会读取一次。如果修改配置文件并希望强制现有会话获取新内容,请发出更改文本搜索词典在字典上输入命令。这可能是一个“虚拟”更新,实际上不会更改任何参数值。

# 12.6.3.同义词词典

此词典模板用于创建用同义词替换单词的词典。不支持短语(使用同义词库模板(第12.6.4节)为此)。同义词词典可以用来克服语言问题,例如,防止英语词干分析器词典将单词“Paris”缩减为“pari”。只要有一个巴黎在同义词词典中划一行,放在英语词干词典例如:

SELECT * FROM ts_debug('english', 'Paris');
   alias   |   description   | token |  dictionaries  |  dictionary  | lexemes
### 12.6.4. Thesaurus Dictionary

 A thesaurus dictionary (sometimes abbreviated as TZ) is a collection of words that includes information about the relationships of words and phrases, i.e., broader terms (BT), narrower terms (NT), preferred terms, non-preferred terms, related terms, etc.

 Basically a thesaurus dictionary replaces all non-preferred terms by one preferred term and, optionally, preserves the original terms for indexing as well. PostgreSQL's current implementation of the thesaurus dictionary is an extension of the synonym dictionary with added *phrase* support. A thesaurus dictionary requires a configuration file of the following format:

# 这是一条评论

示例词:索引词更多示例词:更多索引词。。。

 where the colon (`:`) symbol acts as a delimiter between a phrase and its replacement.

 A thesaurus dictionary uses a *subdictionary* (which is specified in the dictionary's configuration) to normalize the input text before checking for phrase matches. It is only possible to select one subdictionary. An error is reported if the subdictionary fails to recognize a word. In that case, you should remove the use of the word or teach the subdictionary about it. You can place an asterisk (`*`) at the beginning of an indexed word to skip applying the subdictionary to it, but all sample words *must* be known to the subdictionary.

 The thesaurus dictionary chooses the longest match if there are multiple phrases matching the input, and ties are broken by using the last definition.

 Specific stop words recognized by the subdictionary cannot be specified; instead use `?` to mark the location where any stop word can appear. For example, assuming that `a` and `the` are stop words according to the subdictionary:

? 一二:swsw

 matches `a one the two` and `the one a two`; both would be replaced by `swsw`.

 Since a thesaurus dictionary has the capability to recognize phrases it must remember its state and interact with the parser. A thesaurus dictionary uses these assignments to check if it should handle the next word or stop accumulation. The thesaurus dictionary must be configured carefully. For example, if the thesaurus dictionary is assigned to handle only the `asciiword` token, then a thesaurus dictionary definition like `one 7` will not work since token type `uint` is not assigned to the thesaurus dictionary.

### Caution

 Thesauruses are used during indexing so any change in the thesaurus dictionary's parameters *requires* reindexing. For most other dictionary types, small changes such as adding or removing stopwords does not force reindexing.

#### 12.6.4.1. Thesaurus Configuration

 To define a new thesaurus dictionary, use the `thesaurus` template. For example:

创建文本搜索词典同义词库(TEMPLATE=thesaurus,DictFile=mythesaurus,DICTIONARY=pg_catalog.english_stem);

 Here:

* `thesaurus_simple` is the new dictionary's name

* `mythesaurus` is the base name of the thesaurus configuration file. (Its full name will be `$SHAREDIR/tsearch_data/mythesaurus.ths`, where `$SHAREDIR` means the installation shared-data directory.)

* `pg_catalog.english_stem` is the subdictionary (here, a Snowball English stemmer) to use for thesaurus normalization. Notice that the subdictionary will have its own configuration (for example, stop words), which is not shown here.

 Now it is possible to bind the thesaurus dictionary `thesaurus_simple` to the desired token types in a configuration, for example:

ALTER文本搜索配置asciiword、asciiword、hword_asciipart的俄文ALTER映射与同义词库_simple;

#### 12.6.4.2. Thesaurus Example

 Consider a simple astronomical thesaurus `thesaurus_astro`, which contains some astronomical word combinations:

超新星恒星:sn蟹状星云:蟹状星云

 Below we create a dictionary and bind some token types to an astronomical thesaurus and English stemmer:

创建文本搜索词典叙词表(模板=叙词表,DictFile=叙词表,词典=英语词干);

ALTER文本搜索配置asciiword、asciiword、hword_asciipart和同义词库astro、英语词干的俄文ALTER映射;

 Now we can see how it works. `ts_lexize` is not very useful for testing a thesaurus, because it treats its input as a single token. Instead we can use `plainto_tsquery` and `to_tsvector` which will break their input strings into multiple tokens:

选择plainto_tsquery(“超新星恒星”);普莱托·尤茨基

# 12.6.5.伊斯佩尔词典

Ispell字典模板支持形态词典,它可以将一个词的许多不同语言形式规范化为同一个词素。例如,英语Ispell词典可以匹配搜索词的所有变位和变位银行,例如。,银行业, 银行, 银行, 银行的银行的.

标准的PostgreSQL发行版不包括任何Ispell配置文件。许多语言的词典可从以下网站获得:伊斯佩尔 (opens new window)。此外,还支持一些更现代的字典文件格式-迈斯佩尔 (opens new window)(OO\<2.0.1)和亨斯佩尔 (opens new window)(哦>= 2.0.2). 网上有一大串字典OpenOffice维基 (opens new window).

要创建Ispell字典,请执行以下步骤:

  • 下载字典配置文件。OpenOffice扩展文件具有.oxt扩大提取是必要的aff先生.dic文件,将扩展名更改为附上字典。对于某些字典文件,还需要使用命令将字符转换为UTF-8编码(例如,对于挪威语言字典):

    iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff
    iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic
    
  • 将文件复制到$SHAREDIR/tsearch_数据目录

  • 使用以下命令将文件加载到PostgreSQL中:

    CREATE TEXT SEARCH DICTIONARY english_hunspell (
        TEMPLATE = ispell,
        DictFile = en_us,
        AffFile = en_us,
        Stopwords = english);
    

    在这里口述文件, AffFile停止语指定字典、词缀和停止词文件的基本名称。stop words文件的格式与上面为易于理解的字典类型。此处未指定其他文件的格式,但可从上述网站获取。

    Ispell词典通常只识别有限的一组单词,因此它们后面应该有另一个更广泛的词典;例如,一本雪球字典,它能识别一切。

    这个附上Ispell的文件具有以下结构:

prefixes
flag *A:
    .           >   RE      # As in enter > reenter
suffixes
flag T:
    E           >   ST      # As in late > latest
    [^AEIOU]Y   >   -Y,IEST # As in dirty > dirtiest
    [AEIOU]Y    >   EST     # As in gray > grayest
    [^EY]       >   EST     # As in small > smallest

还有字典文件具有以下结构:

lapse/ADGRS
lard/DGRS
large/PRTY
lark/MRS

文件格式字典文件是:

basic_form/affix_class_name

附上文件每个粘贴标志的描述格式如下:

condition > [-stripping_letters,] adding_affix

这里,condition的格式与正则表达式的格式类似。它可以使用分组[...][^...]例如[爱欧]是表示单词的最后一个字母是“是”倒数第二个字母是“一种”,“e”,“一世”,“哦”或者“你”.[^EY]表示最后一个字母既不是“e”也不“是”.

Ispell 词典支持拆分复合词;一个有用的功能。请注意,附加文件应使用复合词控制标记可以参与复合形成的字典单词的语句:

compoundwords  controlled z

以下是挪威语的一些示例:

SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
   {over,buljong,terning,pakk,mester,assistent}
SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
   {sjokoladefabrikk,sjokolade,fabrikk}

MySpell 格式是 Hunspell 的一个子集。这。词缀Hunspell 的文件结构如下:

PFX A Y 1
PFX A   0     re         .
SFX T N 4
SFX T   0     st         e
SFX T   y     iest       [^aeiou]y
SFX T   0     est        [aeiou]y
SFX T   0     est        [^ey]

词缀类的第一行是标题。词缀规则的字段列在标题后面:

  • 参数名称(PFX或SFX)

  • flag(词缀类的名称)

  • 从单词的开头(前缀处)或结尾(后缀处)剥离字符

  • 添加词缀

  • 具有类似于正则表达式格式的条件。

    这个字典文件看起来像字典Ispell的文件:

larder/M
lardy/RT
large/RSPMYT
largehearted

# 笔记

MySpell不支持复合词。Hunspell对复合词有复杂的支持。目前,PostgreSQL只实现基本的拼写复合词操作。

# 12.6.6.雪球词典

Snowball字典模板基于Martin Porter的一个项目,他是流行的Porter英语词干算法的发明者。Snowball现在为许多语言提供词干算法(参见雪球场 (opens new window)更多信息)。每个算法都了解如何将常见的单词变体简化为其语言中的基本拼写或词干拼写。滚雪球词典需要语言参数来标识要使用的词干分析器,还可以选择指定停止词提供要删除的单词列表的文件名。(雪球项目也提供了PostgreSQL的标准停止词列表。)例如,有一个内置定义相当于

CREATE TEXT SEARCH DICTIONARY english_stem (
    TEMPLATE = snowball,
    Language = english,
    StopWords = english
);

stopword文件格式与前面解释的相同。

雪球词典能识别一切,无论它是否能简化单词,所以它应该放在词典列表的末尾。把它放在任何其他字典之前是没有用的,因为令牌永远不会通过它传递到下一个字典。