【问题标题】:Postgres Full-Text Search with Hyphen and Numerals带有连字符和数字的 Postgres 全文搜索
【发布时间】:2019-09-04 19:58:30
【问题描述】:

我观察到 Postgres 的 to_tsvector 函数在我看来有什么奇怪的行为。

SELECT to_tsvector('english', 'abc-xyz');

返回

'abc':2 'abc-xyz':1 'xyz':3

然而,

SELECT to_tsvector('english', 'abc-001');

返回

'-001':2 'abc':1

为什么不这样呢?

'abc':2 'abc-001':1 '001':3

我应该怎么做才能仅通过数字部分进行搜索,而不使用连字符?

【问题讨论】:

    标签: postgresql full-text-search


    【解决方案1】:

    似乎文本搜索解析器将连字符后跟数字识别为有符号整数符号。使用ts_debug()进行调试:

    SELECT * FROM ts_debug('english', 'abc-001');
    
       alias   |   description   | token | dictionaries | dictionary | lexemes 
    -----------+-----------------+-------+--------------+------------+---------
     asciiword | Word, all ASCII | abc   | {simple}     | simple     | {abc}
     int       | Signed integer  | -001  | {simple}     | simple     | {-001}
    

    其他文本搜索配置(例如“simple”而不是“english”)将无济于事,因为解析器本身在这里“有问题”(值得商榷)。

    一种简单的解决方法(除了修改解析器,我从未尝试过)将预处理字符串并用 m-dash () 替换连字符或只是空格以确保它们被标识为 “空格符号”。 (实际有符号整数在此过程中失去负号。)

    SELECT to_tsvector('english', translate('abc-001', '-', '—'))
        @@ to_tsquery ('english', '001');  -- true now
    

    db小提琴here

    【讨论】:

    • 谢谢!调用“翻译”对我不起作用,因为它不适用于此处未提及的其他用例,但这会: WHERE to_tsvector('english', field)) @@ to_tsquery ('english', '001' ) OR to_tsvector('english', field)) @@ to_tsquery('english', '-001');
    【解决方案2】:

    这可以通过 PG13 的 dict-int 插件的 absval 选项来规避。见the official documentation

    但如果您被早期的 PG 版本卡住,这里是查询中“数字或负数”解决方法的通用版本。

    select regexp_replace($$'test' & '1':* & '2'$$::tsquery::text,
                '''([.\d]+''(:\*)?)', '(''\1 | ''-\1)', 'g')::tsquery;
    

    这会导致:

    'test' & ( '1':* | '-1':* ) & ( '2' | '-2' )
    

    它将看起来像正数的词位替换为“数字或负数”类型的子查询。
    双重转换 ::tsquery::text 只是为了展示如何将 tsquery 转换为文本。
    请注意,它也处理前缀匹配数字词位。

    【讨论】:

      猜你喜欢
      • 2012-07-25
      • 2017-04-17
      • 2016-05-30
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多