當前位置:
首頁 >
PostgreSQL 8.3 以上的中文全文索引使用介绍
發布時間:2025/1/21
63
豆豆
生活随笔
收集整理的這篇文章主要介紹了
PostgreSQL 8.3 以上的中文全文索引使用介绍
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
PostgreSQL 8.3 以上的中文全文索引使用介紹 - PostgreSQL 中文維基, PostgreSQL 中文站, PostgreSQL 中國社區, PostgreSQL Chinese community
PostgreSQL 8.3 以上的中文全文索引使用介紹??? From PostgreSQL 中文維基, PostgreSQL 中文站, PostgreSQL 中國社區, PostgreSQL Chinese community
??? Jump to: navigation, search
??? 目錄
??? [隱藏]
??????? 1 前提
??????????? 1.1 安裝 PostgreSQL 4E 包
??????????? 1.2 初始化 PostgreSQL 4E 包
??????????? 1.3 配置PostgreSQL 4E 包
??????? 2 概念
??????? 3 實例
??????????? 3.1 場景設計
??????????? 3.2 設計相關表
??????????? 3.3 書寫觸發器
??????????????? 3.3.1 觸發器函數
??????????????? 3.3.2 創建觸發器
??????????? 3.4 創建全文索引
??????????? 3.5 運行上面SQL代碼
??????????? 3.6 測試!
??????????? 3.7 全文搜索
??????????? 3.8 獲取摘要
??? [編輯] 前提
??? [編輯] 安裝 PostgreSQL 4E 包
??? 使用全文索引最簡單的方法是使用 4E 的 PostgreSQL 包,已經有大量預編譯好的包存在,可以在獲取安裝包里頭找到。
??? [編輯] 初始化 PostgreSQL 4E 包
??? 參考管理員手冊里面的初始化 PostgreSQL 和/或集群。
??? [編輯] 配置PostgreSQL 4E 包
??? 參考管理員手冊里面的配置 PostgreSQL 和/或集群。
??? 特別要注意的是default_text_search_config的配置,一定要按照配置來搞。
??? [編輯] 概念
??? 基于 PostgreSQL 的全文搜索的使用是很簡單的,其基本概念是:
??????? 在數據庫中有個特殊的數據類型,叫做 tsvector;
??????????? tsvector 代表“語意”,語意就是一個詞的概念;
??????????? tsvector 中包括詞和詞的位置,用于相關性(ranking)的計算;
??????? 數據庫具備完整的框架:自動分詞和計算每個詞的位置;
??????? 數據庫具備完整的框架:可以由用戶選定分詞方法(模塊)和使用的詞典;
??????? 數據庫對 tsvector 類型進行倒排索引或者是深度的b-tree(平衡樹索引)提供快速的檢索服務;
??????????? 索引本身如同標準數據庫字段一樣,是在INSERT和UPDATE的時候自動更新的;
??????? 查詢是以SQL語言方式進行的
??????????? 標準的 SELECT
??????????? 一些特殊的操作符,比如 @@ 是全文匹配的操作符
??????????? 一個特殊的 ts_query 類型,用于對查詢本身進行分詞、標記位置等處理,通過全文匹配操作符與 tsvector 類型進行比對
??? 更多信息可以參考官方的文檔
??? [編輯] 實例
??? [編輯] 場景設計
??? 假設我們設計一個保存BBS的帖子的表,為了簡化,我們只有兩個字段:標題和正文,表結構如下:
??? [編輯] 設計相關表
??? 我們設計一個很簡單的表:
??? create table content(
?????? id serial primary key,
?????? subject text,
?????? body text);
??? 其中 subject 字段保存帖子的標題,body字段保存帖子的正文。
??? 然后我們要設計一個保存全文索引內容的表:
??? create table content_search(
????? id integer primary key,
????? subject_fti tsvector,
????? body_fti tsvector,
????? foreign key (id) references content(id));
??? 注意這里的數據類型:tsvector,是PostgreSQL為了全文索引專門制作的數據類型。請用這個類型保存分詞后的內容字段。
??? [編輯] 書寫觸發器
??? 寫一個更新全文的觸發器,觸發器的文檔詳情可以參考:
??? http://www.pgsqldb.org/pgsqldoc-8.1c/plpgsql-trigger.html
??? 我在這里直接寫代碼,很簡單:
??? [編輯] 觸發器函數
??? create or replace function content_trigger() returns trigger as $
??? begin
????? if TG_OP = 'INSERT' then
?????? insert into content_search(id, subject_fti, body_fti) values(NEW.id,
?????? to_tsvector(NEW.subject), to_tsvector(NEW.body));
?????? end if;
????? return NEW;end;$
??? language plpgsql;
??? 我這里先考慮了INSERT的情況,UPDATE的一會兒更新版本的時候再說。
??? [編輯] 創建觸發器
??? create trigger content_table_trig after insert or update on content
?????? for each row execute procedure content_trigger();
??? [編輯] 創建全文索引
??? 給全文索引的表創建索引,我們需要建兩個,給標題和正文各自創建一個:
??? create index content_search_subject_idx on content_search using gin(subject_idx);
??? create index content_search_body_idx on content_search using gin(body_idx);
??? 這里using后頭也可以用gist類型的索引,我在gist和gin的索引類型的區別里討論他們的區別。
??? [編輯] 運行上面SQL代碼
??? 我們創建所有這些對象,方法是把上面的SQL語句保存在一個文件里,比如文件名叫 my_fti_test.sql,然后用psql執行:
???? /usr/local/pgsql/bin psql -d testdb -f my_fti_test.sql
??? 你可能需要換成自己的數據庫名字(-d 后面的),如果還沒有數據庫的話,可能需要創建之:
???? /usr/local/pgsql/bin createdb testdb
??? 這里的psql和 createdb的路徑如果用安裝包的話,缺省在 /usr/local/pgsql/bin里頭,我在上面使用了缺省的路徑。
??? [編輯] 測試!
??? 添加些測試數據:
??? insert into content(subject, body) values('linux和linux',
??? 'linux,linux,linux,linux,linux,linux,linux,linux,linux');
??? insert into content(subject, body) values('linux使用和linux安裝',
??? 'linux,linux,linux,linux,linux應用是一個很復雜的問題');
??? insert into content(subject, body) values('linux應用', 'linux應用是一個
??? 很復雜的問題');
??? insert into content(subject, body) values('linux',
??? 'linux,linux,linux,linux,linux,linux,linux,linux');
??? 注意這里我忽略了 ID 字段,因為我用了缺省值。
??? 可以查詢一下這些表:
????? select * from content;
????? select * from content_search;
??? 看看是啥東西。
??? [編輯] 全文搜索
??? 執行下面的查詢:
??? select subject from mail_archive where id in (
?????? select id from mail_archive_fti where subject_fti @@ 'linux' order by
?????? ts_rank_cd(subject_fti, to_tsquery('linux')), ts_rank_cd(mail_body_fti,
?????? to_tsquery('linux')) );
??? 注意,我們已經有基本的排序:先看subject的關鍵字密度,然后再看正文的。下面的章節將介紹更多的內容。
??? [編輯] 獲取摘要
??? 搜索結果都希望能把摘要拿出來,而不是其中一段東西,那么,這個事情在 4E 的 PostgreSQL 包里面可以這么用:
???? select fts_summary(mail_body, to_tsquery('linux'), 'HighlightAll=1') from
????? mail_archive where id in
???? (select id from mail_archive_fti where mail_body_fti @@ to_tsquery('linux')) limit 1;
??? 注意一下輸出的結果,會發現在搜索詞周圍添加了的高亮標識,而且,查出來的東西就是關鍵詞左近的一些原文。
總結
以上是生活随笔為你收集整理的PostgreSQL 8.3 以上的中文全文索引使用介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 测试用
- 下一篇: DataGridView数据验证Cell