PostgreSQL8.3.X新特性-全文搜索(二)
PostgreSQL8.3.X新特性-全文搜索(二)
附加特性 本节描述在文本搜索里有用的附加的函数和操作符。 [编辑] 操作文档8.3 12.3 控制文本搜索一节显示了裸文本文档如何转换成 tsvector 值。PostgreSQL 还提供了可以用于操作已经是 tsvector 形式的文档的函数。 tsvector || tsvector
setweight(vector tsvector,weight "char") returns tsvector
length(vector tsvector) returns integer
strip(vector tsvector) returns tsvector
[编辑] 操作查询8.3 12.2 表和索引节显示了裸文本查询如何转换成 tsquery 值。PostgreSQL 还提供了可以用于操作已经是 tsquery 形式的查询的函数和操作符。 tsquery && tsquery
tsquery || tsquery
!! tsquery
numnode(query tsquery) returns integer
SELECT numnode(plainto_tsquery('the any')); NOTICE: query contains only stopword(s) or doesn't contain lexeme(s),ignored numnode --------- 0 SELECT numnode('foo & bar'::tsquery); numnode --------- 3 querytree(query tsquery) returns text
SELECT querytree(to_tsquery('!defined')); querytree ----------- [编辑] 查询改写ts_rewrite 族函数搜索一个特定的 tsquery 以获取一个目标子查询是否出现,然后把每个出现都替换成其它的子查询。实际上这个操作是一个tsquery 版本的子字串替换。目标和替换的组合可以认为是一个重写规则。一组这样的重写规则可以成为搜索的强力助手。比如,你可以适用同义词扩展搜索(比如,new york,big apple,nyc,goham)或者把搜索限制起来,把用户导向一些热点主体。这个函数和知识词典(第12.6.4节的功能之间有一些重叠。不过,你可以运行时修改一个重写规则集而不用重建索引,而更新知识词典需要重建索引才能生效。 ts_rewrite (query tsquery,target tsquery,substitute tsquery) returns tsquery
SELECT ts_rewrite('a & b'::tsquery,'a'::tsquery,'c'::tsquery); ts_rewrite ------------ 'b' & 'c' ts_rewrite (query tsquery,select text) returns tsquery
CREATE TABLE aliases (t tsquery PRIMARY KEY,s tsquery); INSERT INTO aliases VALUES('a','c'); SELECT ts_rewrite('a & b'::tsquery,'SELECT t,s FROM aliases'); ts_rewrite ------------ 'b' & 'c'
让我们看看一个真实的宇航搜索的例子。我们会对查询 supernovae 使用表驱动的重写规则进行扩展: CREATE TABLE aliases (t tsquery primary key,s tsquery); INSERT INTO aliases VALUES(to_tsquery('supernovae'),to_tsquery('supernovae|sn')); SELECT ts_rewrite(to_tsquery('supernovae & crab'),'SELECT * FROM aliases'); ts_rewrite --------------------------------- 'crab' & ( 'supernova' | 'sn' ) 我们可以通过更新表来修改重写规则: UPDATE aliases SET s = to_tsquery('supernovae|sn &!nebulae') WHERE t = to_tsquery('supernovae'); SELECT ts_rewrite(to_tsquery('supernovae & crab'),'SELECT * FROM aliases'); ts_rewrite --------------------------------------------- 'crab' & ( 'supernova' | 'sn' &!'nebula' ) 如果有很多重写规则的话,重写可能会很慢,因为它需要检查每一个可能会命中的规则。要过滤掉明显不是候选者的规则,我们可以使用tsquery 类型的包含操作符。在下面的例子力,我们只选取那些可能匹配原始查询的规则: SELECT ts_rewrite('a & b'::tsquery,s FROM aliases WHERE ''a & b''::tsquery @> t'); ts_rewrite ------------ 'b' & 'c' [编辑] 用于自动更新的触发器在使用独立的字段存储文档的 tsvector 表现形式的时候,我们必须创建一个触发器,用来在文档字段内容改变的时候更新 tsvector 字段。有两个内置的触发器函数可以干这个事情,当然,你也可以写自己的。 tsvector_update_trigger(tsvector_column_name,config_name,text_column_name [,... ]) tsvector_update_trigger_column(tsvector_column_name,config_column_name,... ]) 这些触发器函数自动从一个或多个文本字段里计算一个 tsvector 字段,同时在通过 CREATE TRIGGER 声明的参数的控制下。下面是一个使用它们的例子: CREATE TABLE messages ( title text,body text,tsv tsvector ); CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON messages FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(tsv,'pg_catalog.english',title,body); INSERT INTO messages VALUES('title here','the body text is here'); SELECT * FROM messages; title | body | tsv ------------+-----------------------+---------------------------- title here | the body text is here | 'bodi':4 'text':5 'titl':1 SELECT title,body FROM messages WHERE tsv @@ to_tsquery('title & body'); title | body ------------+----------------------- title here | the body text is here 在创建触发器之后,任何在 title 或者 body 内的改变都会自动对应到 tsv 里面,而不用应用操心这些事情。 第一个触发器参数必须是要更新的 tsvector 字段。第二个参数声明执行转换的时候需要用的文本搜索配置。对于 tsvector_update_trigger,配置名就以第二个触发器参数的方式给出。它必须是上面所示那样的有模式修饰的,这个触发器的行为就不会因为 search_path 的改变而改变。对于 tsvector_update_trigger_column,第二个触发器参数是另外一个表字段的名字,这个字段类型必须是 regconfig。这样就允许我们可以针对不同行使用不同的配置。剩下的参数是文本字段的名称(类型是 text,varchar 或者 char)。这些将被以给出的顺序包含在文档中。NULL 值会被忽略(但是其它字段仍将被索引)。 内置的触发器的一个限制是它们把所有输入字段都看成是一样的。要想用不同方式处理字段 -- 比如,给 body 赋予不同的权重 -- 我们就需要书写一个客户化的触发器。下面是一个使用 PL/pgSQL 做为触发器语言的例子: CREATE FUNCTION messages_trigger() RETURNS trigger AS $$ begin new.tsv:= setweight(to_tsvector('pg_catalog.english',coalesce(new.title,'')),'A') || setweight(to_tsvector('pg_catalog.english',coalesce(new.body,'D'); return new; end $$ LANGUAGE plpgsql; CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON messages FOR EACH ROW EXECUTE PROCEDURE messages_trigger(); 要注意,在触发器里创建 tsvector 数值的时候,明确地声明配置名称是非常重要的,这样字段的内容就不会被 default_text_search_config 的改变所影响。没能这么做可能会导致诸如转储和恢复之后搜索结果改变的问题。 [编辑] 收集文档的统计信息函数 ts_stat 可用于检查你的配置和查找候选屏蔽词。 ts_stat(sqlquery text,[ weights text,] OUT word text,OUT ndoc integer,OUT nentry integer) returns setof record sqlquery 是一个文本值,包含一个 SQL 查询,它必须返回单个 tsvector 字段。ts_stat 执行这个查询并返回包含在这个 tsvector 数据里有关每个独立的语意(lexeme)(单词)的统计,返回的字段有
如果提供了权重,那么只计算包含该权重的词。 比如,在文档里找出十个最常见的词: SELECT * FROM ts_stat('SELECT vector FROM apod') ORDER BY nentry DESC,ndoc DESC,word LIMIT 10; 同样的东西,但是只计算权重 A 和 B 的词: SELECT * FROM ts_stat('SELECT vector FROM apod','ab') ORDER BY nentry DESC,word LIMIT 10; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |