欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Oracle?數(shù)據(jù)庫(kù)中的全文搜索整體流程分析

 更新時(shí)間:2024年04月01日 15:03:08   作者:engchina  
Oracle 是一種功能強(qiáng)大的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),它提供了各種功能來(lái)處理和管理大量的數(shù)據(jù),這篇文章主要介紹了Oracle?數(shù)據(jù)庫(kù)中的全文搜索功能,需要的朋友可以參考下

0. 引言

這篇文章會(huì)介紹 Oracle Text 索引,旨在引導(dǎo)您了解創(chuàng)建文本索引、執(zhí)行文本查詢和維護(hù)文本索引的基礎(chǔ)知識(shí)。

Oracle Text 為 Oracle 數(shù)據(jù)庫(kù)提供全文索引功能,允許您通過(guò)指定內(nèi)容中的單詞、短語(yǔ)或其他文本模式來(lái)搜索文本內(nèi)容(例如 VARCHAR2 或 CLOB 數(shù)據(jù))。

Oracle Text 是數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)組件,允許您在 Oracle 數(shù)據(jù)庫(kù)中的文本數(shù)據(jù)中進(jìn)行快速全文搜索。例如,它可以讓您在地址字段中查找拼寫錯(cuò)誤的單詞,或者獲取包含特定短語(yǔ)的 Microsoft Word 文檔列表。

雖然表面上它類似于 LIKE 運(yùn)算符的索引版本,但存在許多差異。

Oracle Text 對(duì)數(shù)據(jù)庫(kù)中的文本內(nèi)容創(chuàng)建基于單詞(word-based)的索引。該內(nèi)容的范圍可以從 VARCHAR2 列中的幾個(gè)單詞到存儲(chǔ)在 BLOB 列中的多章節(jié) PDF 文檔(甚至存儲(chǔ)在文件系統(tǒng)外部、URL 或云存儲(chǔ)上)。

這篇文章主要面向開發(fā)人員和 DBA,內(nèi)容涵蓋創(chuàng)建索引、基本搜索功能和索引維護(hù)。

1. 整體流程

整體流程如下,

我們將創(chuàng)建一個(gè)名為“user_data”的簡(jiǎn)單表,其中包含客戶信息。其中包括記錄 ID 的數(shù)字列、客戶名稱的 VARCHAR2 列、訂單金額的數(shù)字列以及銷售代表所做的任何注釋的 VARCHAR2 列。

我們將填充該表,然后在注釋列上創(chuàng)建一個(gè)文本索引。

然后,我們將使用 Oracle Text CONTAINS 運(yùn)算符完成各種類型的查詢。我們還將在注釋列上顯示一些帶有全文搜索的混合查詢,并在其他關(guān)系列上顯示附加過(guò)濾器。

接下來(lái),我們將了解如何同步和優(yōu)化 Oracle Text 索引。

最后,我們將了解如何在對(duì)象存儲(chǔ)上索引二進(jìn)制文件,例如 Microsoft Word 或 PDF 文件。

2. 創(chuàng)建索引

2-1. 創(chuàng)建一個(gè)簡(jiǎn)單的表

我們將創(chuàng)建一個(gè)簡(jiǎn)單的表來(lái)保存模擬用戶銷售記錄。它包含一個(gè)用于記錄 ID 的數(shù)字列、一個(gè)用于客戶名稱的 varchar 列、另一個(gè)用于銷售額的數(shù)字列以及另一個(gè)用于注釋的 varchar 列。將以下內(nèi)容復(fù)制到“工作表”區(qū)域,然后按“運(yùn)行語(yǔ)句”按鈕:

create table user_data
(id number,
 name varchar2(100),
 amount number(17,2),
 note varchar2(2000)
)

插入幾行數(shù)據(jù),

insert into user_data
    select 1, 'John Smith', 123.45, 'First order from John Smith.' from dual
        union
    select 2, 'Mary Poppins', 67.89, 'First ever order from Marie Poppins.' from dual
        union
    select 3, 'John Smith', 99.45, 'Second order from Johnny Smith.' from dual
commit;

檢查表中是否有數(shù)據(jù),

select * from user_data

2-2. 創(chuàng)建文本索引

文本索引是域索引(domain index)的一個(gè)示例。域索引是特定類型數(shù)據(jù)(或“域”)的專門索引。為了告訴內(nèi)核要?jiǎng)?chuàng)建什么類型的索引,我們使用特殊語(yǔ)法“INDEXTYPE IS …”。最常見(jiàn)的文本索引類型,也是我們?cè)谶@里使用的,是 CONTEXT 索引類型。

復(fù)制并運(yùn)行以下 SQL,這將在表的 TEXT 列上創(chuàng)建索引。

create index myindex on user_data(note) indextype is ctxsys.context

檢查數(shù)據(jù)庫(kù)視圖中的索引,

select index_name, index_type, status from user_indexes
where index_name = 'MYINDEX'

這樣就有了您的索引,index_type 為“DOMAIN”,狀態(tài)為“VALID”。文本索引必須有效才能使用。在大型表上創(chuàng)建的索引可能會(huì)顯示為 INPROGRS,這意味著索引創(chuàng)建正在進(jìn)行中,但尚未準(zhǔn)備好使用。

我們還可以在“文本數(shù)據(jù)字典”中查找。這是用戶 CTXSYS 擁有的一組視圖,專門用于 Oracle Text 索引。這些視圖均以“CTX_”為前綴,所有用戶都可以查看。運(yùn)行以下命令:

select idx_name, idx_table, idx_text_name from ctx_user_indexes

這告訴我們索引 MYINDEX 是在表 USER_DATA 的“NOTE”列上創(chuàng)建的。

2-3. 查看創(chuàng)建的基礎(chǔ)表

文本索引作為一組基礎(chǔ)表來(lái)實(shí)現(xiàn)。它們通常采用 DR < i n d e x n a m e > <indexname> <indexname> 形式,其中后綴表示表的特定類型。通常不需要知道這些索引中有什么,但其中一個(gè)(“dollar I”表)特別有趣。

注意:子表列表將隨數(shù)據(jù)庫(kù)版本和所選索引選項(xiàng)的不同而變化。您可能會(huì)看到與此處顯示的列表不同的列表。

您應(yīng)該看到列出了幾個(gè)表。單擊旁邊的三角形,打開 DR M Y I N D E X MYINDEX MYINDEXI 的表定義。

我們看到一個(gè)列列表。我們主要感興趣的是 TOKEN_TEXT。

我們之前討論了 Oracle Text 如何使用“基于單詞”的索引。更準(zhǔn)確地說(shuō),它使用“基于令牌”的索引,因?yàn)榱钆撇灰欢ㄊ菃卧~(盡管通常是)。 “$I”表包含所有索引標(biāo)記的列表,我們可以使用以下查詢查看它們:

select token_text from dr$myindex$i

注意到列表中的任何內(nèi)容了嗎?文本中并未出現(xiàn)所有單詞 - 缺少“from”。這是因?yàn)樗恢付?ldquo;停用詞” - 在搜索中不是很有用的常見(jiàn)詞,但可能會(huì)占用索引中的大量空間。默認(rèn)情況下,我們不會(huì)對(duì)它們建立索引 - 盡管使用高級(jí)選項(xiàng),我們可以告訴系統(tǒng)對(duì)所有單詞建立索引,或者提供我們不想索引的單詞的“自定義非索引字表”。默認(rèn)的停用詞列表將隨語(yǔ)言的不同而變化,并且取決于數(shù)據(jù)庫(kù)的默認(rèn)語(yǔ)言設(shè)置(自治數(shù)據(jù)庫(kù)始終為英語(yǔ))。您可以按照此處的示例自定義停用詞列表:創(chuàng)建停用詞列表和添加停用詞。

目前我們不需要了解任何有關(guān)底層索引表的信息。但查看已索引的單詞很有用,并且在嘗試找出特定查詢?yōu)楹稳绱诉\(yùn)行時(shí),有時(shí)值得參考此列表(下一步將介紹查詢)。

3. 運(yùn)行查詢

我們將探討用于查詢 Oracle Text 索引的 CONTAINS 運(yùn)算符。

在這個(gè)章節(jié),您將:

  • 探索 CONTAINS 文本查詢運(yùn)算符
  • 查看各種基本文本搜索
  • 了解 SCORE() 運(yùn)算符如何幫助您對(duì)查詢結(jié)果進(jìn)行排名

3-1. 運(yùn)行文本查詢

首先熟悉 USER_DATA 中包含的文本。

select * from user_data

3-2. CONTAINS 運(yùn)算符

要搜索 Oracle Text CONTEXT 索引,必須使用 CONTAINS 運(yùn)算符。 CONTAINS 特定于該類型的索引。與“普通”索引不同,無(wú)論有沒(méi)有索引,您都無(wú)法獲得相同的結(jié)果。如果不存在 CONTEXT 索引,CONTAINS 根本不起作用。

CONTAINS 是一個(gè)返回?cái)?shù)字的函數(shù)。它幾乎總是以 WHERE CONTAINS(…) > 0 的形式使用。如果返回值大于零,則該行有匹配項(xiàng),如果為零則沒(méi)有匹配項(xiàng)。

CONTAINS 需要兩個(gè)或三個(gè)參數(shù)。第三個(gè)是可選的,我們稍后再討論。兩個(gè)必需的參數(shù)是:

  • 要搜索的列的名稱
  • 要搜索的字符串值。該字符串可以是文字字符串,也可以是任何計(jì)算結(jié)果為字符串的字符串(VARCHAR2 或 CLOB)。

讓我們嘗試一個(gè)簡(jiǎn)單的例子。我們將查找單詞“John”:

select * from user_data 
    where contains ( note, 'john' ) > 0

請(qǐng)注意,我們找到了包含單詞“John”的一行。但是,我們沒(méi)有找到包含“Johnny”的行。這說(shuō)明了 Oracle Text 搜索與簡(jiǎn)單的 LIKE 搜索(例如 WHERE TEXT LIKE ‘%John%’)之間的眾多差異之一。 LIKE 執(zhí)行子字符串搜索,而 CONTAINS 則(默認(rèn)情況下)查找整個(gè)單詞。

您還可以嘗試搜索大寫的 JOHN。你會(huì)得到相同的結(jié)果。與 LIKE 搜索不同,CONTAINS 搜索(至少對(duì)于英文索引)不區(qū)分大小寫。

3-3. 混合查詢

CONTAINS 是一個(gè) SQL 運(yùn)算符。當(dāng)然,您可以將其與任何其他 WHERE 子句結(jié)合起來(lái)。例如,我們可以查找 AMOUNT 值小于 100 的單詞“Smith”。讓我們嘗試一下:

select * from user_data
    where amount < 100
    and   contains ( note, 'smith' ) > 0

3-4. OR 查詢

CONTAINS 的搜索字符串參數(shù)有自己的語(yǔ)法,具有各種內(nèi)部運(yùn)算符,例如 AND、OR、NEAR 等。我們?cè)谶@里僅展示一個(gè)示例,有關(guān)更多信息,您應(yīng)該參閱文檔。

之前,我們搜索“John”但沒(méi)有找到“Johnny”。讓我們搜索一下:

select * from user_data 
    where contains ( note, 'john OR johnny' ) > 0

果然,現(xiàn)在我們兩者都找到了。

3-5. 通配符

運(yùn)行先前搜索的另一種方法是使用通配符 %。與標(biāo)準(zhǔn) SQL 一樣,百分號(hào) % 匹配任何字符串,下劃線 _ 字符匹配任何單個(gè)字符。

因此 john% 將匹配“john”、“johnny”、“johnnie”、“johnston”等。 l_se 將匹配“lose”,但不匹配“loose”。

由于通配符僅適用于索引單詞,因此它們永遠(yuǎn)不會(huì)匹配空格。因此 qui%step 將匹配“quickstep”,但不會(huì)匹配短語(yǔ)“quick step”。

我們來(lái)嘗試一下:

select * from user_data 
  where contains ( note, 'john%' ) > 0

3-6. 短語(yǔ)搜索

如果您想在同一文檔中查找兩個(gè)單詞,您可以執(zhí)行 AND 搜索,類似于上面的 OR 搜索。如果您想一起查找兩個(gè)單詞,只需將它們作為短語(yǔ)輸入即可。無(wú)需添加引號(hào)或任何內(nèi)容,兩個(gè)單詞一起自動(dòng)構(gòu)成短語(yǔ)搜索,并且僅當(dāng)它們一起出現(xiàn)在索引文本中時(shí)才會(huì)匹配。

select * from user_data 
  where contains ( note, 'first order' ) > 0

Note that only matches the first row where the actual phrase “first order” appears, and not the other row where the two words appear, but not as a phrase.

3-7. 模糊搜索(Fuzzy searches)

如果您犯了錯(cuò)誤或根本不記得確切的拼寫,您可以進(jìn)行模糊搜索。它不僅會(huì)找到原始搜索詞,還會(huì)找到所有與其相似的搜索詞。

select * from user_data 
  where contains ( note, 'fuzzy(popins)' ) > 0

請(qǐng)注意,搜索詞“popins”存在拼寫錯(cuò)誤。但通過(guò)模糊搜索,它實(shí)際上找到了包含正確單詞“Poppins”的結(jié)果。

3-8. 附近的搜索

您可以使用 NEAR 運(yùn)算符查找彼此接近的單詞。它將查找彼此指定距離內(nèi)的單詞。例如,以下查詢未找到任何結(jié)果。因?yàn)?ldquo;order”和“smith”之間有兩個(gè)單詞,但我們指定它們之間最多有 1 個(gè)單詞。

select * from user_data 
  where contains ( note, 'near((order, smith), 1)' ) > 0

下一個(gè)查詢找到結(jié)果,因?yàn)樗_指定了“order”和“smith”之間的距離 2。

select * from user_data 
  where contains ( note, 'near((order, smith), 2)' ) > 0

請(qǐng)注意,默認(rèn)情況下,近運(yùn)算符中的單詞順序并不重要,除非 ORDER 參數(shù)顯式設(shè)置為 TRUE。但在短語(yǔ)搜索中,單詞的順序確實(shí)很重要。

You can find a list of query operators here: Contains Query Operators.

4. 維護(hù)索引

到目前為止,我們已經(jīng)了解了如何創(chuàng)建和查詢 Oracle Text 索引。這是 Oracle Text 的基礎(chǔ)知識(shí),但我們需要討論索引維護(hù)下的幾個(gè)主題。

默認(rèn)情況下,Oracle Text 索引不是事務(wù)性的。索引表發(fā)生更改后,必須先同步索引,然后才能通過(guò)搜索找到新數(shù)據(jù)。

對(duì) Oracle Text 索引進(jìn)行多次更改后,由于索引碎片和垃圾(已刪除)數(shù)據(jù)在索引中累積,其性能將達(dá)不到理想狀態(tài)。為了讓索引達(dá)到最佳狀態(tài),我們必須對(duì)其進(jìn)行優(yōu)化。

在本章節(jié)中,您將:

  • 看到索引沒(méi)有自動(dòng)更新
  • 了解如何手動(dòng)或自動(dòng)同步索引
  • 看到索引隨著時(shí)間的推移變得碎片化
  • 了解如何優(yōu)化索引

4-1. 同步

讓我們向 USER_DATA 中插入一個(gè)新行。復(fù)制以下內(nèi)容并單擊“運(yùn)行語(yǔ)句”按鈕:

insert into user_data values (4, 'Mike Smith', 98.76, 'Third one from Mike Smith.');
commit;

現(xiàn)在嘗試查詢剛剛插入的數(shù)據(jù):

select * from user_data
    where contains ( note, 'mike' ) > 0

當(dāng)你運(yùn)行它時(shí),你將不會(huì)得到任何結(jié)果。請(qǐng)記住 CONTAINS 僅適用于 CONTEXT 索引。如果該索引不是最新的,那么結(jié)果也不會(huì)是最新的。為了獲得正確的結(jié)果,我們必須同步索引。執(zhí)行此操作的基本方法是調(diào)用 PL/SQL 過(guò)程 CTX_DDL.SYNC_INDEX(您的用戶需要具有 CTXAPP 角色才能訪問(wèn)該過(guò)程,或者已被顯式授予 EXECUTE ON CTXSYS.CTX_DDL)。索引名稱作為參數(shù)傳遞給過(guò)程。

運(yùn)行這個(gè)命令同步索引,

execute ctx_ddl.sync_index ('myindex')

現(xiàn)在再次嘗試之前的“mike”查詢,它將起作用。

4-2. 提交時(shí)自動(dòng)同步

手動(dòng)運(yùn)行 SYNC_INDEX 非常高效,并且可以讓您完全控制。但是,您可以讓索引自動(dòng)同步,方法是指定應(yīng)在提交時(shí)同步,或者指定定期的時(shí)間段(例如每分鐘)來(lái)執(zhí)行同步。

首先刪除當(dāng)前索引:

drop index myindex

每當(dāng)需要非默認(rèn)索引行為時(shí),我們都會(huì)對(duì)索引使用 PARAMETERS 子句。這里我們將指定 SYNC(ON COMMIT) 以使其在 COMMIT 時(shí)自動(dòng)同步:

create index myindex on user_data(note) indextype is ctxsys.context
    parameters ('sync (on commit)')

現(xiàn)在我們將向表中添加一個(gè)新行并搜索它:

insert into user_data values (5, 'Peter Williams', 110.68, 'Canceled order from Peter Williams.' );
commit;

我們將找到新行,而無(wú)需調(diào)用 CTX_DDL.SYNC_INDEX。

select * from user_data 
    where contains ( note, 'williams' ) > 0

4-3. 按時(shí)間間隔自動(dòng)同步

SYNC(ON COMMIT) 很方便,但在高事務(wù)率情況下并不理想。它可能會(huì)導(dǎo)致事務(wù)在等待上一個(gè) SYNC 完成時(shí)被延遲。相反,您可以選擇在特定時(shí)間段執(zhí)行 SYNC。

該時(shí)間段越長(zhǎng)(通常選擇五分鐘),您的索引需要優(yōu)化的次數(shù)就越少。但是,如果您需要近乎實(shí)時(shí)的同步,則可以選擇低至一秒的時(shí)間段。

時(shí)間間隔SYNC使用數(shù)據(jù)庫(kù)調(diào)度程序,因此在19c及之前您必須具有CREATE JOB權(quán)限才能使用它。

刪除現(xiàn)有索引:

drop index myindex

現(xiàn)在再次創(chuàng)建索引,但這次指定應(yīng)每分鐘同步一次。時(shí)間段的語(yǔ)法來(lái)自 DBMS_SCHEDULER。

create index myindex on user_data(note) indextype is ctxsys.context
    parameters ('sync (every "freq=minutely; interval=1")')

現(xiàn)在插入一個(gè)新行

insert into user_data values (6, 'Paul Williams', 77.36, 'Returned order from Paul Williams.' );
commit;

搜索新行。最初,您可能會(huì)發(fā)現(xiàn)它找不到新行,但繼續(xù)重復(fù)查詢,它會(huì)在一分鐘內(nèi)起作用。

select * from user_data 
    where contains (note, 'paul') > 0;

4-4. 優(yōu)化

檢查“$I”表,現(xiàn)在我們已經(jīng)完成了索引的更新,讓我們?cè)倏匆幌?$I 表中的索引詞列表。運(yùn)行以下命令:

select token_text from dr$myindex$i

您應(yīng)該看到現(xiàn)在有兩個(gè)單詞“order”和“williams”的條目。我們不會(huì)擔(dān)心到底為什么(盡管請(qǐng)注意它們是在上次更新中使用的),但我們只是說(shuō)這是索引碎片的一個(gè)示例。

優(yōu)化索引,我們可以使用 ctx_ddl 包中的另一個(gè) PL/SQL 命令來(lái)優(yōu)化索引:ctx_ddl.optimize_index。這需要兩個(gè)強(qiáng)制參數(shù):索引名稱和要執(zhí)行的優(yōu)化類型。常見(jiàn)值為“FULL”或“REBUILD”。我們將選擇“FULL”:

execute ctx_ddl.optimize_index('myindex', 'FULL')

現(xiàn)在再次嘗試從 $I 表中進(jìn)行先前的選擇。現(xiàn)在只有一個(gè)“order”條目和一個(gè)“williams”條目 - 這些單詞的索引信息已被壓縮為每個(gè)單詞的一行。

您現(xiàn)在應(yīng)該在創(chuàng)建 Oracle Text 索引、針對(duì)這些索引運(yùn)行基本查詢以及維護(hù)這些索引方面具備良好的基礎(chǔ)。

5. 對(duì)象存儲(chǔ)上的索引文件

在之前的實(shí)驗(yàn)中,我們向您展示了如何對(duì)簡(jiǎn)單的 VARCHAR2 文本進(jìn)行索引。但 Oracle Text 的能力遠(yuǎn)不止于此。例如,它可以自動(dòng)識(shí)別和處理大約 150 種不同的二進(jìn)制文件格式。有 PDF 文檔嗎?沒(méi)問(wèn)題。想要索引 Powerpoint 演示文稿中的所有文本嗎?當(dāng)然可以,為什么不呢?

Oracle Text 可以處理文件系統(tǒng)或 URL 上保存的文件,但對(duì)于本例,我們將把文件直接加載到數(shù)據(jù)庫(kù)的 BLOB(二進(jìn)制長(zhǎng)對(duì)象)列中。

完成之前的所有實(shí)驗(yàn)后,此實(shí)驗(yàn)是可選的。您可以索引自己的文件,或使用我們提供的簡(jiǎn)單的 Microsoft Word 文件。

在本章節(jié)中,您將:

  • 將文件復(fù)制到對(duì)象存儲(chǔ)
  • 創(chuàng)建“預(yù)授權(quán)請(qǐng)求”URL 來(lái)訪問(wèn)這些文件
  • 使用 DBMS_CLOUD.GET_OBJECT 將文件加載到數(shù)據(jù)庫(kù)中
  • 創(chuàng)建一個(gè)首選項(xiàng),告訴 Text 使用 AUTO_FILTER

索引文件并使用內(nèi)容詞進(jìn)行搜索

5-1. 將文件加載到對(duì)象存儲(chǔ)

轉(zhuǎn)到 Oracle Cloud 中的主菜單(請(qǐng)注意,這與數(shù)據(jù)庫(kù)操作的菜單不同 - 它可能在不同的選項(xiàng)卡中打開)。

打開“漢堡包”菜單,然后選擇“存儲(chǔ)”,然后選擇“對(duì)象存儲(chǔ)和歸檔存儲(chǔ)”下的存儲(chǔ)桶。

在“存儲(chǔ)桶”頁(yè)面中,從“搜索分區(qū)”框中選擇您的根分區(qū)。

然后點(diǎn)擊“創(chuàng)建存儲(chǔ)桶”,您可以提供名稱或僅保留默認(rèn)名稱。單擊創(chuàng)建。

現(xiàn)在單擊新創(chuàng)建的存儲(chǔ)桶。

滾動(dòng)到頁(yè)面底部找到對(duì)象并單擊上傳。

在“上傳對(duì)象”面板中,您可以使用文件選擇器從計(jì)算機(jī)中選擇某些 Office 或 PDF 文件,或?qū)⑺鼈兺戏诺巾?yè)面上。

如果您沒(méi)有任何合適的文件,您可以從這里下載一個(gè)簡(jiǎn)單的 Microsoft Word 文檔

關(guān)于 PDF 文件的說(shuō)明:Oracle Text 無(wú)法處理純圖像的 PDF 文件(即使它們是文本圖像 - 我們沒(méi)有 OCR 功能)。 PDF 文件必須嵌入文本。有時(shí),PDF 文件會(huì)受到文本訪問(wèn)保護(hù),或使用無(wú)法讀取的特殊“位圖”字體。不過(guò),絕大多數(shù) PDF 文件都可以使用。

選擇文件后,單擊“上傳”按鈕即可完成。然后單擊“關(guān)閉”,您應(yīng)該會(huì)看到存儲(chǔ)桶中列出了您的文件。

為文件創(chuàng)建預(yù)驗(yàn)證請(qǐng)求 (PAR)。

對(duì)于存儲(chǔ)桶中的每個(gè)文件,我們需要?jiǎng)?chuàng)建一個(gè)“預(yù)驗(yàn)證請(qǐng)求”。這是一個(gè)特殊的 URL,其中包含文件的嵌入式訪問(wèn)密鑰。這意味著任何有權(quán)訪問(wèn)該 URL 的人都可以訪問(wèn)該文件,但實(shí)際上不可能猜測(cè)該 URL。

單擊文件右側(cè)的“三點(diǎn)”菜單,然后選擇“創(chuàng)建預(yù)驗(yàn)證請(qǐng)求”。

在彈出的面板上,選擇“對(duì)象”,然后單擊“創(chuàng)建預(yù)驗(yàn)證請(qǐng)求”按鈕。

您將看到一個(gè)“預(yù)驗(yàn)證請(qǐng)求詳細(xì)信息”面板,單擊“復(fù)制”按鈕復(fù)制 URL,然后將其保存到文本文件以供以后使用。對(duì)每個(gè)要索引的文件重復(fù)此操作。

注意:不要擔(dān)心可怕的“不會(huì)再顯示”。您可以隨時(shí)創(chuàng)建另一個(gè) PAR。

5-2. 將文件加載到數(shù)據(jù)庫(kù)中

在瀏覽器中打開“數(shù)據(jù)庫(kù)操作”選項(xiàng)卡(或者如果需要,可以使用之前的說(shuō)明重新打開它)并轉(zhuǎn)到 SQL。

創(chuàng)建一個(gè)表來(lái)保存文件數(shù)據(jù)。運(yùn)行以下語(yǔ)句:

create table documents (name varchar2(50), content blob)

將文件從對(duì)象存儲(chǔ)加載到表中。

對(duì)您存儲(chǔ)的每個(gè)文件運(yùn)行一次,替換為 PAR URL(您在上一步中保存的)和短名稱或描述。不要忘記為每個(gè)文件指定不同的名稱/描述。

declare
   body blob;
begin
   body := dbms_cloud.get_object(null, 'https://objectstorage.uk...HelloWorld.docx');
   insert into documents values ('Hello World as an MS Word file', body);
end;

通過(guò)獲取名稱和 LOB 列的大小來(lái)檢查文件是否已正確加載

select name, dbms_lob.getlength(content) from documents

5-3. 索引文檔

創(chuàng)建過(guò)濾器首選項(xiàng)。

Oracle Text 很聰明地發(fā)現(xiàn),如果它對(duì) BLOB 列建立索引,那么它顯然是在處理二進(jìn)制文件,需要通過(guò) AUTO_FILTER 才能被識(shí)別并轉(zhuǎn)換為文本。所以實(shí)際上我們可以像以前一樣創(chuàng)建一個(gè)簡(jiǎn)單的文本索引。但為了說(shuō)明如何自定義索引選項(xiàng),我們將向您展示如何創(chuàng)建一個(gè)首選項(xiàng),明確告訴文本使用 AUTO_FILTER,覆蓋其索引的數(shù)據(jù)類型的任何默認(rèn)值。我們還將根據(jù)我們的偏好設(shè)置一個(gè) TIMEOUT 屬性,告訴它過(guò)濾任何特定文件的時(shí)間不要超過(guò) 10 秒。

我們需要?jiǎng)?chuàng)建一個(gè)首選項(xiàng),然后設(shè)置該首選項(xiàng)的屬性。這些都是使用名為 ctx_ddl 的包完成的,任何具有 CTXAPP 角色的用戶都可以執(zhí)行該包。由于這里有兩個(gè)語(yǔ)句,因此使用“運(yùn)行腳本”按鈕運(yùn)行它們是最簡(jiǎn)單的?;蛘撸怀鲲@示這兩個(gè)語(yǔ)句并按“運(yùn)行”。

exec ctx_ddl.create_preference ('my_filter_pref', 'AUTO_FILTER')
exec ctx_ddl.set_attribute ('my_filter_pref', 'TIMEOUT', 10)

(如果您需要再次運(yùn)行該程序,您可以調(diào)用 ctx_ddl.drop_preference,僅將首選項(xiàng)名稱作為參數(shù))

使用我們的過(guò)濾器首選項(xiàng)創(chuàng)建索引。

對(duì)于任何具有非標(biāo)準(zhǔn)選項(xiàng)的索引,我們使用 PARAMETERS 子句(我們之前在 SYNC 選項(xiàng)中看到過(guò)它)。該子句采用單個(gè)字符串,該字符串主要是首選項(xiàng)類型和首選項(xiàng)名稱的列表。在這里,我們的首選項(xiàng)類型是“filter”,首選項(xiàng)名稱是“my_filter_pref”。如果我們想添加更多文件,我們還將包括同步(提交時(shí))。

create index documents_index on documents(content)
  indextype is ctxsys.context
  parameters ('filter my_filter_pref sync(on commit)')

如果該語(yǔ)句出現(xiàn)任何問(wèn)題 - 就像您拼寫錯(cuò)誤您的偏好一樣,它可能會(huì)創(chuàng)建失敗的索引。在創(chuàng)建新索引之前,您需要?jiǎng)h除該索引。

5-4. 搜索文件

我們的 CONTAINS 將針對(duì)索引的 CONTENT 列運(yùn)行,但由于它是二進(jìn)制的,因此沒(méi)有必要選擇它,因此我們只需選擇 NAME 列。如果您不為 HelloWorld 文檔編制索引,則可以在此處替換為您自己的搜索字符串。

select name from documents where contains (content, 'world') > 0

可選:獲取片段(上下文中突出顯示的搜索詞)

我們無(wú)法讀取表中的二進(jìn)制文檔,但我們可以讓 Text 用它來(lái)做一些事情。 CTX_DOC 包有各種處理索引文檔的過(guò)程。讓我們看一下 CTX_DOC.SNIPPET,它獲取搜索詞周圍的文檔塊。它通常從 PL/SQL 調(diào)用,但如果我們傳入索引名稱和我們正在查看的行的 ROWID 值,我們也可以從 SQL SELECT 查詢調(diào)用它。我們還必須告訴它所使用的搜索詞。所以我們得到:

select name, ctx_doc.snippet('DOCUMENTS_INDEX', rowid, 'world') from documents where contains (content, 'world') > 0

如果您正在搜索其他文檔,請(qǐng)不要忘記將“world”更改兩次。

CTX_DOC包含許多用于處理單個(gè)文檔的函數(shù)。值得一看文檔。

如果您已完成此可選模塊,您就會(huì)知道 Oracle Text 可以處理的不僅僅是數(shù)據(jù)庫(kù)中的短文本。為什么不嘗試更多的文件呢?也許將“文檔”文件夾中的所有文件加載到數(shù)據(jù)庫(kù)中,最終,您將能夠找到您多年前編寫的難以捉摸的 Powerpoint,但不記得它的文件名。

6. (可選)情感分析

情緒分析可以回答“產(chǎn)品評(píng)論是正面還是負(fù)面?”等問(wèn)題?;?ldquo;客戶滿意還是不滿意?”例如,從包含特定產(chǎn)品的多個(gè)評(píng)論的文檔集中,您可以確定表明該產(chǎn)品是好還是壞的總體情緒。

Oracle Text 使用戶能夠使用經(jīng)過(guò)訓(xùn)練以識(shí)別情感元數(shù)據(jù)的情感分類器對(duì)主題或文檔執(zhí)行情感分析。

Oracle Text 可以使用基本的內(nèi)置“詞袋”分類器(針對(duì)英文文本)執(zhí)行情感分析。為了獲得更好的結(jié)果或使用其他語(yǔ)言,您可以使用一組培訓(xùn)文檔來(lái)訓(xùn)練您自己的分類器。

本章節(jié)將使用Oracle數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)分類器,并用它來(lái)分析一組有關(guān)相機(jī)評(píng)論的文檔的情緒。

在本章節(jié)中,您將:

  • 使用內(nèi)置的默認(rèn)分類器分析文檔的情緒
  • 使用單獨(dú)的訓(xùn)練文檔集訓(xùn)練自定義分類器
  • 使用經(jīng)過(guò)訓(xùn)練的分類器來(lái)分析文檔
  • 比較兩種分析方法的準(zhǔn)確性

6-1. 使用默認(rèn)分類器

加載評(píng)論數(shù)據(jù)進(jìn)行分析,這是您要分析的實(shí)際數(shù)據(jù)。在本例中,我們將創(chuàng)建一個(gè)“camera_review”表并將評(píng)論文本加載到該表中。

create table camera_reviews(review_id number primary key, review_text varchar2(2000))

插入評(píng)論數(shù)據(jù)。您需要在運(yùn)行之前選擇所有行,或者使用“運(yùn)行 SQL 腳本”按鈕,

insert into camera_reviews values (1, 'this camera is OK');
insert into camera_reviews values (2, 'the camera is absolutely fantastic');
insert into camera_reviews values (3, 'the camera is terrible');
insert into camera_reviews values (4, 'another fantastic camera from Nikon');
insert into camera_reviews values (5, 'What a terrible camera from Canon');
insert into camera_reviews values (6, 'camera is not too bad, but ok for the price');
insert into camera_reviews values (7, 'lens is not too bad, love the looks of this camera');
insert into camera_reviews values (8, 'the Sony camera has a lot of new features, although a bit pricey');

檢查所有行是否已加載。您應(yīng)該看到 8 行。

exec ctx_ddl.create_preference('review_lexer', 'AUTO_LEXER')

使用我們剛剛創(chuàng)建的首選項(xiàng)和 NOPOPULATE 關(guān)鍵字創(chuàng)建評(píng)論數(shù)據(jù)的索引,

create index camera_revidx on camera_reviews(review_text)
indextype is ctxsys.context 
parameters ('lexer review_lexer NOPOPULATE');

6-2. 運(yùn)行情緒分析

情緒分析使用 PL/SQL 過(guò)程 CTX_DOC.SENTIMENT_AGGREGATE 逐行運(yùn)行。返回一個(gè)數(shù)值,表示文檔的情緒,范圍在 -100 到 100 之間,其中 -100 最大為負(fù)面,0 為中性,100 最大為正面。該函數(shù)采用索引的名稱和 TEXTKEY,TEXTKEY 可以是行的唯一鍵值,或者如果表沒(méi)有唯一鍵,則為 ROWID 值(我們可以使用 CTX_DOC.SET_KEY_TYPE 在使用鍵和 rowids 之間進(jìn)行交換。

因此,為了獲取每個(gè)評(píng)論文本及其計(jì)算出的情緒,我們可以運(yùn)行以下命令:

select ctx_doc.sentiment_aggregate(
    index_name => 'camera_revidx',
    textkey    => review_id 
  ) sentiment, review_text
from camera_reviews;

6-3. 使用經(jīng)過(guò)訓(xùn)練的分類器

訓(xùn)練分類器涉及提供一組已知為正面、中性或負(fù)面的訓(xùn)練文檔。此類文檔可能已經(jīng)過(guò)人工審核,或者您可能會(huì)使用用戶提供的其他元數(shù)據(jù)(例如星級(jí)評(píng)定)。

訓(xùn)練使用稱為支持向量機(jī)(SVM)的機(jī)器學(xué)習(xí)算法。

您提供的訓(xùn)練文檔越多,分類器就越好。由于我們?cè)谶@里只提供很少的示例文檔,因此分類器將非常粗糙。

加載訓(xùn)練數(shù)據(jù),我們將加載評(píng)論培訓(xùn)表。在下一步中,我們將為每條評(píng)論貼上相關(guān)情緒的標(biāo)簽。

首先,創(chuàng)建一個(gè)名為“training_camera”的表來(lái)保存訓(xùn)練數(shù)據(jù),

create table training_camera(train_id number primary key, train_text varchar2(2000))

將訓(xùn)練數(shù)據(jù)插入訓(xùn)練表,

insert into training_camera values( 1,'this camera is OK');
insert into training_camera values( 2,'the camera is absolutely fantastic');
insert into training_camera values( 3,'the camera is terrible');
insert into training_camera values( 4,'i love the lens, but overall ok camera');
insert into training_camera values( 5,'the camera has mediocre lens, but a lot of nice features');
commit;

用情感標(biāo)記訓(xùn)練數(shù)據(jù),我們使用一個(gè)單獨(dú)的表來(lái)保存與“training_camera”表中每一行相關(guān)的情緒:

create table training_category(doc_id number, category number, category_desc varchar2(100))

對(duì)于訓(xùn)練數(shù)據(jù)表中的每一行,我們必須插入一行來(lái)指示該行的類別。類別是代表中性、正面或負(fù)面的整數(shù)值,如下表所列。 “categoy_desc”列作為人類可讀的注釋包含在此處,在分類過(guò)程中既不是必需的,也不是使用的。

整數(shù)意義
0中立
1積極
2負(fù)

鑒于此,我們可以如下創(chuàng)建類別行(您可能希望返回訓(xùn)練表以檢查每行涉及的文本)

insert into training_category values( 1, 0, ‘neutral’);
insert into training_category values( 2, 1, ‘positive’);
insert into training_category values( 3, 2, ‘negative’);
insert into training_category values( 4, 0, ‘neutral’);
insert into training_category values( 5, 0, ‘neutral’);

6-4. 創(chuàng)建 SVM 情感分類器

exec ctx_ddl.create_preference('classifier_camera','SENTIMENT_CLASSIFIER')

您可以選擇設(shè)置分類器“classifier_camera”的屬性。

exec ctx_ddl.set_attribute('classifier_camera','MAX_FEATURES','1000');
exec ctx_ddl.set_attribute('classifier_camera','NUM_ITERATIONS','600');

6-5. 索引訓(xùn)練集

在訓(xùn)練表上創(chuàng)建索引。該索引僅用于其關(guān)聯(lián)的元數(shù)據(jù),因此可以使用“nopopulate”選項(xiàng)創(chuàng)建,并且速度非??臁?duì)于經(jīng)過(guò)訓(xùn)練的分類器,您確實(shí)需要使用 AUTO_LEXER,我們將允許它使用默認(rèn)的英語(yǔ)詞法分析器 (BASIC_LEXER)。

create index training_idx on training_camera(train_text) 
indextype is ctxsys.context parameters ('nopopulate');

6-6. 訓(xùn)練分類器

過(guò)程 SA_TRAIN_MODEL(SA 用于情感分析)獲取有關(guān)訓(xùn)練和類別表(及其各個(gè)列)的信息,以及我們剛剛創(chuàng)建的索引和分類器首選項(xiàng)的名稱。然后,這將生成一個(gè)模型,其名稱在第一個(gè)參數(shù)中給出 - 在本例中為“my_clsfier”

begin
  ctx_cls.sa_train_model (
    clsfier_name => 'my_clsfier',
    index_name   => 'training_idx',
    docid        => 'train_id',
    cattab       => 'training_category',
    catdocid     => 'doc_id',
    catid        => 'category', 
    pref_name    => 'classifier_camera'
    );
end;

6-7. 使用經(jīng)過(guò)訓(xùn)練的分類器運(yùn)行情感分析

運(yùn)行情感分析的過(guò)程與上次非常相似,只是這次我們需要提供分類器名稱,而不是允許其默認(rèn)。
請(qǐng)記住,我們?cè)赾amera_reviews 表上已經(jīng)有一個(gè)“nopopulate”文本索引 - 如果我們?cè)谏弦徊街袥](méi)有創(chuàng)建它,我們需要在使用新分類器之前在此處創(chuàng)建它。

select ctx_doc.sentiment_aggregate(
    index_name   => 'camera_revidx',
    textkey      => review_id,
    clsfier_name => 'my_clsfier'
  ) sentiment, review_text
from camera_reviews;

我們還可以在同一個(gè)查詢中運(yùn)行經(jīng)過(guò)訓(xùn)練和未經(jīng)訓(xùn)練的分類器,以比較兩者的效率。當(dāng)然,這是一個(gè)精心選擇訓(xùn)練詞的人為示例,但在現(xiàn)實(shí)世界中,假設(shè)訓(xùn)練集大小合理,您應(yīng)該會(huì)看到經(jīng)過(guò)訓(xùn)練的分類器具有明顯更好的性能。

select review_text,
  ctx_doc.sentiment_aggregate('camera_revidx', review_id) as default_sentiment,
  ctx_doc.sentiment_aggregate('camera_revidx', review_id, clsfier_name => 'my_clsfier') as trained_sentiment
from camera_reviews order by trained_sentiment;

You can find more details of sentiment analysis here: [Sentiment Analysis](You can find more details of sentiment analysis here: Sentiment Analysis.
).

refer: Full-Text Search in Oracle Database ShareStart

完結(jié)!

相關(guān)文章

最新評(píng)論