为什么PostgreSQL在ts_headline()中剥离HTML实体?

nie*_*aki 6 html postgresql postgresql-9.5

我正在编写一个全文搜索功能的原型,它将在搜索结果中返回找到的文档的"标题".这是Postgres文档中稍微修改过的示例:

SELECT ts_headline('english',
  'The most common type of search is to find all documents containing given query terms <b>and</b> return them in <order> of their similarity to the query.',
  to_tsquery('query & similarity'),
  'StartSel = XXX, StopSel = YYY');
Run Code Online (Sandbox Code Playgroud)

我期望的是什么样的

"documents containing given XXXqueryYYY terms <b>and</b> return them in <order> of their XXXsimilarityYYY to the XXXqueryYYY."
Run Code Online (Sandbox Code Playgroud)

我得到的是

"documents containing given XXXqueryYYY terms  and  return them in   of their XXXsimilarityYYY to the XXXqueryYYY."
Run Code Online (Sandbox Code Playgroud)

看起来像HTML标签一样远程看起来的所有内容都被剥离并替换为单个空格字符(注意周围的双重空格and).

我没有在文档中找到任何声明Postgres假设输入文本是HTML并且用户希望剥离标签的地方.该API允许压倒一切的StartSel,并StopSel从默认的<b></b>,所以我认为它是为了满足更广泛的用例.

在我缺少的文档中是否有一些设置或注释?

小智 6

<b>并被</b>识别为标签令牌。默认情况下它们被忽略。您需要修改现有配置或创建新配置:

=# CREATE TEXT SEARCH CONFIGURATION english_tag (COPY = english);
=# alter text search configuration english_tag
   add mapping for tag with simple;
Run Code Online (Sandbox Code Playgroud)

那么标签不会被跳过:

=# select * from ts_debug('english_tag', 'query <b>test</b>');
   alias   |   description   | token |  dictionaries  |  dictionary  | lexemes
-----------+-----------------+-------+----------------+--------------+---------
 asciiword | Word, all ASCII | query | {english_stem} | english_stem | {queri}
 blank     | Space symbols   |       | {}             | (null)       | (null)
 tag       | XML tag         | <b>   | {simple}       | simple       | {<b>}
 asciiword | Word, all ASCII | test  | {english_stem} | english_stem | {test}
 tag       | XML tag         | </b>  | {simple}       | simple       | {</b>}
Run Code Online (Sandbox Code Playgroud)

但即使在这种情况下 ts_headline 也会跳过标签。因为它是 硬编码的

#define HLIDREPLACE(x)  ( (x)==TAG_T )
Run Code Online (Sandbox Code Playgroud)

当然有一个解决方法。可以创建您自己的文本搜索解析器扩展。GitHub上的示例。并改变

#define HLIDREPLACE(x)  ( (x)==TAG_T )
Run Code Online (Sandbox Code Playgroud)

#define HLIDREPLACE(x)  ( false )
Run Code Online (Sandbox Code Playgroud)