日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

PostgreSQL · 特性介绍 · 全文搜索介绍

發(fā)布時間:2025/3/19 数据库 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PostgreSQL · 特性介绍 · 全文搜索介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

背景

在日常的數(shù)據(jù)處理中,我們經(jīng)常會有這樣的需求:從一個文本中尋找某個字符串(比如某個單詞)。

對這個需求,我們可以用類似這樣的SQL完成:SELECT * FROM tbl WHERE text LIKE '%rds PostgreSQL%';(找到含有“rds PostgreSQL”的文本)

現(xiàn)在我們考慮一些特殊的情形:

  • 需要查找的文本特別多,特別大;
  • 不做單純的字符串匹配,而是考慮自然語言的一些特性,比如匹配某一類字符串(域名,人名)或者匹配單詞的所有形式(不考慮它的詞性及變化,比如have,has,had都匹配出來);
  • 對中文自然語言特性的支持。
  • 那么此時再用以上的“SELECT ... LIKE ...”就不明智了,因為對數(shù)據(jù)庫來說,這樣的SQL必然走的是全表掃描,那么當文本特別多,特別大的時候,查找效率就會很低。

    另外,這樣的SQL也不會智能到可以處理自然語言的特性。

    怎么辦呢?PostgreSQL(以下簡稱PG)提供了強大的全文搜索功能可以滿足這樣的需求。

    對文本的預處理

    全文搜索首先需要對文本預處理,包括3步:

  • 將文本分解成一個個token,這些token可以是數(shù)字,單詞,域名,人名,email的格式等等。在PG中可以定義一個parser來做這個工作。
  • 將第一步分解成的token標準化,所謂的標準化就是利用一些規(guī)則將token分好類(比如人名是一類,域名是一類等等)。標準化后的token我們稱之為lexeme。在PG中是通過定義一個詞典來做這個工作。PG里最簡單的詞典simple的標準化過程就是將大寫字母轉(zhuǎn)成小寫字母。
  • 對文本打分,優(yōu)化查找過程。比如對于待查找的詞,文本1匹配的數(shù)量大于文本2匹配的數(shù)量,那么在這個查找過程,文本1的優(yōu)先級大于文本2的優(yōu)先級。
  • 在PG中,以上對文本的預處理可以通過一個函數(shù)to_tsvector來完成,函數(shù)的返回值是tsvector這個數(shù)據(jù)類型。

    另外,對于待查找的單詞,我們也要用to_tsquery這個函數(shù)包裝起來,函數(shù)的返回值是tsquery這個數(shù)據(jù)類型。

    一個簡單的例子見下面,to_tsquery里的參數(shù)可以使用運算符(&:與,|:或,!:非):

    SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');?column? ----------t

    Quick Start

    在了解了這些概念之后,我們用實際的例子來玩一玩PG的全文搜索。

    我們在client端輸入以下命令,dFp顯示的是所有的parser,這里只有一個默認parser(default)。

    dFp+ default 顯示默認parser(default)的詳細信息:parse的過程(5個函數(shù)),parse的Token類型(asciihword, asciiword...)。

    sbtest=# \dFpList of text search parsersSchema | Name | Description ------------+---------+---------------------pg_catalog | default | default word parser (1 row)sbtest=# \dFp+ defaultText search parser "pg_catalog.default"Method | Function | Description -----------------+----------------+-------------Start parse | prsd_start | (internal)Get next token | prsd_nexttoken | (internal)End parse | prsd_end | (internal)Get headline | prsd_headline | (internal)Get token types | prsd_lextype | (internal)Token types for parser "pg_catalog.default"Token name | Description -----------------+------------------------------------------asciihword | Hyphenated word, all ASCIIasciiword | Word, all ASCIIblank | Space symbolsemail | Email addressentity | XML entityfile | File or path namefloat | Decimal notationhost | Hosthword | Hyphenated word, all lettershword_asciipart | Hyphenated word part, all ASCIIhword_numpart | Hyphenated word part, letters and digitshword_part | Hyphenated word part, all lettersint | Signed integernumhword | Hyphenated word, letters and digitsnumword | Word, letters and digitsprotocol | Protocol headsfloat | Scientific notationtag | XML taguint | Unsigned integerurl | URLurl_path | URL pathversion | Version numberword | Word, all letters (23 rows)

    輸入dF+ english,給出標準化各類英語token時所用到的dictionary:

    sbtest=# \dF+ english Text search configuration "pg_catalog.english" Parser: "pg_catalog.default"Token | Dictionaries -----------------+--------------asciihword | english_stemasciiword | english_stememail | simplefile | simplefloat | simplehost | simplehword | english_stemhword_asciipart | english_stemhword_numpart | simplehword_part | english_stemint | simplenumhword | simplenumword | simplesfloat | simpleuint | simpleurl | simpleurl_path | simpleversion | simpleword | english_stem

    創(chuàng)建以default為parser的配置defcfg,并增加token映射,這里我們只關(guān)心email, url, host:

    sbtest=# CREATE TEXT SEARCH CONFIGURATION defcfg (PARSER = default); CREATE TEXT SEARCH CONFIGURATION sbtest=# ALTER TEXT SEARCH CONFIGURATION defcfg ADD MAPPING FOR email,url,host WITH simple; ALTER TEXT SEARCH CONFIGURATION

    建好配置defcfg后,我們看看利用defcfg對文本進行處理的結(jié)果。這里使用to_tsvector函數(shù),可以看到email,url,host都被識別出來了:

    sbtest=# select to_tsvector('defcfg','xxx yyy xxx@taobao.com yyy@sina.com http://google.com/123 12345 ');to_tsvector -----------------------------------------------------------------------'google.com':4 'google.com/123':3 'xxx@taobao.com':1 'yyy@sina.com':2 (1 row)

    在實際對表內(nèi)的文本做全文搜索時,一般對目標列建立gin索引(也就是倒排索引,詳情見官方文檔),這樣可以加快查詢效率,具體操作如下:

    sbtest=# CREATE TABLE t1(c1 text); CREATE TABLE sbtest=# CREATE INDEX c1_idx ON t1 USING gin(to_tsvector('defcfg', c1)); CREATE INDEX sbtest=# \d t1Table "public.t1"Column | Type | Modifiers --------+------+-----------c1 | text | Indexes:"c1_idx" gin (to_tsvector('defcfg'::regconfig, c1))

    這里我們插入2條文本,并做一些匹配:

    sbtest=# INSERT INTO t1 VALUES('xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345'); INSERT 0 1 sbtest=# INSERT INTO t1 VALUES('xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345'); INSERT 0 1 sbtest=# select * from t1;c1 -------------------------------------------------------------xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345 (2 rows)sbtest=# select * from t1 where to_tsvector('defcfg',c1) @@ 'google.com';c1 -------------------------------------------------------------xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345 (2 rows)sbtest=# select * from t1 where to_tsvector('defcfg',c1) @@ to_tsquery('google.com & yyy@sina.com');c1 -------------------------------------------------------------xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345 (2 rows)sbtest=# select * from t1 where to_tsvector('defcfg',c1) @@ to_tsquery('google.com & xxx@gmail.com');c1 ------------------------------------------------------------xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345 (1 row)

    以上的操作都是針對英文,實際上對中文也是支持的,不過會稍微麻煩點,因為中文的token必須通過分詞才能產(chǎn)生,所以需要先裝分詞的組件scws和zhparser,具體可以參考這篇博文。

    結(jié)語

    本文對PG的全文搜索做了一個入門級的介紹,方便用戶快速上手,如果需要對全文搜索作更深入的研究,建議閱讀官方文檔第12章。

    總結(jié)

    以上是生活随笔為你收集整理的PostgreSQL · 特性介绍 · 全文搜索介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。