您的位置:首页 > 数据库 > Oracle

oracle全文索引之停用词的通配符功能

2010-01-08 14:46 330 查看
全文索引停用词的设置在前面的文章中已经介绍过了,这里简单说明记录一下停用词在查询时候需要注意的地方。

Oracle10g中,如果安装语言为中文,默认的LEXER为CHINESE_VGRAM_LEXER,默认的停用词语言也为中文。这篇通过对比中文环境和英文环境来说明停用词查询的一些特点。

SQL> show user

USER is "MYUSER"

SQL> CREATE TABLE T (ID NUMBER, DOCS VARCHAR2(1000));

Table created.

SQL> INSERT INTO T VALUES (1, 'This example test stopword.');

1 row created.

SQL> INSERT INTO T VALUES (2, 'Oracle9i chinese language environment default stopword are english.');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT;

Index created.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'This') > 0;

no rows selected

英文环境下允许单独查询停用词,但是不会返回结果。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'are english') > 0;

ID DOCS

--- --------------------------------------------------

2 Oracle9i chinese language environment default stop

word are english.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'is english') > 0;

ID DOCS

--- --------------------------------------------------

2 Oracle9i chinese language environment default stop

word are english.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'stopword are english') > 0;

ID DOCS

--- --------------------------------------------------

2 Oracle9i chinese language environment default stop

word are english.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'stopword is english') > 0;

ID DOCS

--- --------------------------------------------------

2 Oracle9i chinese language environment default stop

word are english.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'are stopword') > 0;

ID DOCS

--- --------------------------------------------------

1 This example test stopword.

2 Oracle9i chinese language environment default stop

word are english.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'are example') > 0;

ID DOCS

--- --------------------------------------------------

1 This example test stopword.


面这些查询,由于are、is都是停用词,因此可以认为是一个替代符,代替任何单词。而且查询语句中包含的停用词不仅可以替代文档中本身的停用词,还可以
替代任何有意义的单词,如上面对ARE STOPWORD的查询分别对应了DEFAULT STOPWORD和TEST STOPWORD



SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'stopword english') > 0;

no rows selected

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'default is stopword') > 0;

no rows selected

最后两个查询说明停用词虽然可以替换任何词,但是无论是文档中的停用词还是查询语句中包含的停用词,对必须对应一个单词,如果直接将停用词所在位置的单词忽略掉是不会返回结果的。仅这一点上,停用词有点像通配符“_”。

SQL> SELECT * FROM V$VERSION;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE 10.2.0.1.0 Production

TNS for Linux: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 - Production

下面是中文环境的测试

SQL> CREATE TABLE T (ID NUMBER, DOCS VARCHAR2(1000));

表已创建。

SQL> INSERT INTO T VALUES (1, '这个例子测试停用词');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, 'Oracle10g中文环境默认也是中文');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT;

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '这个') > 0;

SELECT * FROM T WHERE CONTAINS(DOCS, '这个') > 0

*第 1 行出现错误:

ORA-29902: 执行 ODCIIndexStart() 例行程序中出错

ORA-20000: Oracle Text error:

DRG-10817: CONTAINS 搜索词包含禁用词或禁用词的词组: 这个对于中文环境,如果查询只包含停用词,那么查询会报错,这一点和英文环境明显不同。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '也是中文') > 0;

ID DOCS

---------- --------------------------------------------------

2 Oracle10g中文环境默认也是中文

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '就是中文') > 0;

ID DOCS

---------- --------------------------------------------------

2 Oracle10g中文环境默认也是中文

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '还是中文') > 0;

ID DOCS

---------- --------------------------------------------------

2 Oracle10g中文环境默认也是中文

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '不是中文') > 0;

未选定行

由于“也是”、“就是”和“还是”都是停用词,索引查询2到查询4都可以返回结果。但是“不是”不属于停用词,因此,通过不是查询无法返回结果。这个测试和英文停用词的测试很像。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '默认也是中文') > 0;

ID DOCS

---------- --------------------------------------------------

2 Oracle10g中文环境默认也是中文

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '默认就是中文') > 0;

未选定行

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '默认还是中文') > 0;

未选定行

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '默认不是中文') > 0;

未选定行

这次在查询语句中,停用词两边都包含了内容,这时候发现停用词似乎没有起作用,只有全文匹配的查询生效了。感觉是由于中文的切词要比英文复杂,因此不好判断查询短语中是否包含了停用词。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '环境默认') > 0;

ID DOCS

---------- ----------------------------------------------------------

2 Oracle10g中文环境默认也是中文

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '也是默认') > 0;

未选定行

两个查询也说明了中文和英文环境的不同。中文环境中,查询语句中的停用词似乎只能替换停用词,而不能再替换其他有意义的词汇了。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '默认中文') > 0;

未选定行

最后一个查询和英文环境一致,停用词必须占一个词的位置。

SQL> SELECT * FROM V$VERSION;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE 10.2.0.1.0 Production

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 - Production
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: