2013-10-15 23 views
5

我在Rails应用程序中使用pg_search gem来针对用户 - 他们的BIOS和相关技能模型进行搜索。用户是开发商,所以他们的技能,包括像“CSS”,“C++”,“C#”,“目标C”,等等使用pg_search匹配特殊字符(例如#,+)

我最初用以下搜索范围

pg_search_scope :search, 
    against: [:bio], 
    using: {tsearch: {dictionary: "english", prefix: true}}, 
    associated_against: {user: [:fname, :lname], skills: :name} 

但是,如果您在这种情况下搜索“C++”,则会得到包含“CSS”(等等)的结果。我改为使用“简单”的字典的范围和去除前缀:

pg_search_scope :search_without_prefix, 
    against: [:bio], 
    using: {tsearch: {dictionary: "simple"}}, 
    associated_against: {user: [:fname, :lname], skills: :name} 

这种固定的一些事情 - 例如,搜索“C++”不显示“CSS”。但是,搜索“C++”或“C#”仍然匹配列出了“C”或“Objective C”的用户

我绝对可以做一个基本的ILIKE匹配,但希望在可能的情况下使用pg_search完成此操作。

回答

2

我会评论,但我没有足够的声望呢。

我一直在研究pg_search这让我更深入PostgreSQL全文搜索。这是一个复杂的模块,但它有ts_debug()命令来帮助理解如何分析输入字符串。测试字符串“C++ CSS C#Objective C”的ts_debug()输出非常明显。它看起来像“#和‘+’被视为在英语中的默认配置的空白。我想你可能必须修改PostgreSQL的解析器得到你想要的行为。

postgres=# SELECT * FROM ts_debug('english', 'C++ CSS C# Objective C'); 
    alias | description | token | dictionaries | dictionary | lexemes 
-----------+-----------------+-----------+----------------+--------------+---------- 
asciiword | Word, all ASCII | C   | {english_stem} | english_stem | {c} 
blank  | Space symbols | +   | {}    |    | 
blank  | Space symbols | +   | {}    |    | 
asciiword | Word, all ASCII | CSS  | {english_stem} | english_stem | {css} 
blank  | Space symbols |   | {}    |    | 
asciiword | Word, all ASCII | C   | {english_stem} | english_stem | {c} 
blank  | Space symbols | #   | {}    |    | 
asciiword | Word, all ASCII | Objective | {english_stem} | english_stem | {object} 
blank  | Space symbols |   | {}    |    | 
asciiword | Word, all ASCII | C   | {english_stem} | english_stem | {c} 
(10 rows) 

BTW,这里是一个非常有用的教程,如果你想学习PostgreSQL的全文搜索:http://shisaa.jp/postset/postgresql-full-text-search-part-1.html

UPDATE:

我发现PostgreSQL的全文检索中的解决方案。它涉及到使用test_parser扩展,记录在这里:http://www.postgresql.org/docs/9.1/static/test-parser.html

首先一些配置在psql需要:

postgres=# CREATE EXTENSION test_parser; 

postgres=# CREATE TEXT SEARCH CONFIGURATION testcfg (PARSER = testparser); 

postgres=# ALTER TEXT SEARCH CONFIGURATION testcfg 
    ADD MAPPING FOR word WITH english_stem; 

现在可以指数测试字符串并看到喜欢“C++”的术语是作为单独的令牌进行处理,根据需要:

postgres=# SELECT to_tsvector('testcfg', 'C++ CSS C# Objective C#GT40 GT40 added joined'); 
           to_tsvector         
---------------------------------------------------------------------------- 
'#gt40':6 'ad':8 'c':5 'c#':3 'c++':1 'css':2 'gt40':7 'join':9 'object':4 
(1 row) 

问题仍然是如何将其整合到pg_search中。我正在看下一个。

相关问题