【问题标题】:How do I SQL query for words with punctuation in Postgresql?如何在 Postgresql 中对带有标点符号的单词进行 SQL 查询?
【发布时间】:2011-07-18 06:45:52
【问题描述】:

如果我在数据库中存储了这样的字符串/短语:

  • 什么是 Q 型操作?
  • 程序员指南
  • A.B.C 的编码

有没有办法像"Programmers""abc""q-type"一样传递查询参数并让它找到"Programmer's""A.B.C""Q-type"

【问题讨论】:

    标签: sql postgresql search


    【解决方案1】:

    您可以尝试使用带有 TRANSLATE 功能的 ILIKE,请参阅 here

    例如:translate(field, '.-\'', '')

    【讨论】:

    • aw 这将是搜索简单字符串的完美短期解决方案,但我无法在 Rails 中转义该撇号! Article.find(:conditions => ["translate(articles.title, '.-\'', '') ILIKE ?", query]) throws ...unterminated quoted string... (尝试了几种转义方法)。可能与 tsvector 一起使用,更可能是 solr。谢谢!
    • 哎呀,也许为了逃避撇号,你必须加倍:''
    • 使用 ruby​​ 提供的通用单引号语法可能会有所帮助:Article.find(:conditions => [ %q{translate(articles.title, '.-\'', '') ILIKE ?}, query])。否则 ruby​​ 将捕获您试图传递给 sql 的 \,并且您必须使用 2 或 3 个 '\'。 Ruby 不会像双引号字符串那样在单引号字符串中转义。即puts('1\n2'); puts("3\n4") #=> 1\n2*newline*3*newline*4*newline*
    【解决方案2】:

    这听起来像你想要一些类似的东西:

    http://www.postgresql.org/docs/9.0/static/fuzzystrmatch.html

    我不能 100% 确定这是否能满足您的需求。

    编辑我必须在本地运行它来检查(在 Windows 上使用 PostgreSQL 9.0)

    这是我发现的:

    template1=> select soundex('Programmers'), soundex('Programmer''s');
     soundex | soundex
    ---------+---------
     P626    | P626
    (1 row)
    
    
    template1=> select soundex('abc'), soundex('A.B.C.');
     soundex | soundex
    ---------+---------
     A120    | A120
    (1 row)
    
    
    template1=> select soundex('Q-type'), soundex('q-type');
     soundex | soundex
    ---------+---------
     Q310    | Q310
    (1 row)
    

    因此,如果您要执行 soundex(colname) = soundex(<user param>) 应该会在 where 子句中为您提供所需的内容。

    您需要安装 fuzzystrmatch 模块:

    psql -U <dbowner> -d <database> -f SHAREDIR/contrib/fuzzystrmatch.sql

    请参阅有关如何定位 SHAREDIR

    的文档

    编辑我刚刚注意到我忽略了什么,我认为这与ts_vector 功能相结合可能会让您达到您的目标。

    【讨论】:

      【解决方案3】:

      这是另一个相关的链接。在将其与搜索字符串进行比较之前,从所有标点符号中去除该字段的值。

      SQL Server: How do you remove punctuation from a field?

      【讨论】:

        【解决方案4】:

        Postgres 支持模式匹配,因此您可以在 where 子句中构建正则表达式 http://www.postgresql.org/docs/8.3/static/functions-matching.html

        【讨论】:

          【解决方案5】:

          tsvector

          使用 tsvector 类型,它是 PostgreSQL 文本搜索功能的一部分。

          postgres> select 'What are Q-type Operations?'::tsvector;
                        tsvector               
          -------------------------------------
           'Operations?' 'Q-type' 'What' 'are'
          (1 row)
          

          您也可以在 tsvector 上使用熟悉的运算符:

          postgres> select 'What are Q-type Operations?'::tsvector
          postgres>        || 'A.B.C''s of Coding'::tsvector;
                                     ?column?                           
          --------------------------------------------------------------
           'A.B.C''s' 'Coding' 'Operations?' 'Q-type' 'What' 'are' 'of'
          

          From tsvector documentation:

          tsvector 值是不同词位的排序列表,这些词是经过规范化以合并同一词的不同变体的词(有关详细信息,请参阅第 12 章)。在输入过程中自动完成排序和重复消除

          如果您还想进行特定于语言的规范化,例如删除常用词(“the”、“a”等)和乘法,请使用 to_tsvector 函数。它还为文本搜索的不同单词分配权重:

          postgres> select to_tsvector('english',
          postgres> 'What are Q-type Operations? A.B.C''s of Coding');
                                to_tsvector                       
          --------------------------------------------------------
           'a.b.c':7 'code':10 'oper':6 'q':4 'q-type':3 'type':5
          (1 row)
          

          全面的文本搜索

          显然,对查询中的每一行都这样做会很昂贵——因此您应该将 tsvector 存储在单独的列中并使用 ts_query() 来搜索它。这也允许您在 tsvector 上创建一个 GiST 索引。

          postgres> insert into text (phrase, tsvec)
          postgres>   values('What are Q-type Operations?',
          postgres>   to_tsvector('english', 'What are Q-type Operations?'));
          INSERT 0 1
          

          使用 tsquery 和 @@ 运算符完成搜索:

          postgres> select phrase from text where tsvec @@ to_tsquery('q-type');
                     phrase            
          -----------------------------
           What are Q-type Operations?
          (1 row)
          

          【讨论】:

            【解决方案6】:

            Postgresql 通过将文本输入转换为tsvector 类型来支持全文搜索:

            steve@steve@[local] =# select input, to_tsvector('english', input)\
               from (values('What are Q-type Operations?'),('Programmer''s Guide'),('A.B.C''s of Coding')) x(input);
                        input            |            to_tsvector             
            -----------------------------+------------------------------------
             What are Q-type Operations? | 'oper':6 'q':4 'q-type':3 'type':5
             Programmer's Guide          | 'guid':3 'programm':1
             A.B.C's of Coding           | 'a.b.c':1 'code':4
            (3 rows)
            

            如您所见,默认使用的词干将使“programming”、“programmer”和“programmer's”完全匹配。

            您通常会通过索引 tsvector 列或表达式来使用它,然后使用 @@ 运算符将其与 tsquery 匹配,例如:

            steve@steve@[local] =# select input, to_tsvector('english', input) \
               from (values('What are Q-type Operations?'),('Programmer''s Guide'),('A.B.C''s of Coding')) x(input)\
               where to_tsvector('english', input) @@ plainto_tsquery('english', 'programmers');
                   input        |      to_tsvector      
            --------------------+-----------------------
             Programmer's Guide | 'guid':3 'programm':1
            (1 row)
            

            plainto_tsquery 在这里分析用户输入字符串,并生成一个查询,其中查询中的每个非停用词都必须由 tsvector 匹配。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-02-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多