oracle全文索引之SECTION GROUP

Oracle中文全文索引 环境Oracle 9.0.2 Oracle全文索引的基本知识一、历史背景Oracle数据库的全文检索技术已经非常完美,Oracle Text使Oracle9i具备了强大的文本检索能力和智能化的文本管理能力。Oracle Text是Oracle9i采用的新名称,在Oracle8/8i中它被称作Oracle interMedia Text,在Oracle8以前它的名称是Oracle 阅读详情

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的NULL_SECTION_GROUP。
Oracle的全文索引的SECTION GROUP属性用来支持包含内部结构的文档,比如HTML、XML文档等。使用了SECTION GROUP属性,可以在查询文档的时候指定在文档的哪一部分进行查询。可以将查询范围限定在标题中。

这 篇文章首先介绍最简单的NULL_SECTION_GROUP,如果DATASTORE的属性没有设置为URL_DATASTORE且FILTER的属性 没有设置为INSO_FILTER,则 NULL_SECTION_GROUP就是默认的SECTION_GROUP,否则HTML_SECTION_GROUP为默认 SECTION_GROUP。NULL_SECTION_GROUP的含义从名称上已经可以看出,就是没有设置SECTION GROUP,但Oracle还是提供了两个预定义的SECTION:SENTENCE和PARAGRAPH。下面简单介绍 NULL_SECTION_GROUP,并说明SENTENCE和PARAGRAPH的设置和使用。

SQL> conn myuser/myuser
Connected.
SQL> CREATE TABLE T (ID NUMBER, DOCS VARCHAR2(100));

Table created.

SQL> INSERT INTO T VALUES (1, 'A SIMPLE EXAMPLE FOR SECTION GROUP, TEST NULL_SECTION_GROUPATTRIBUTE.');

1 row created.

SQL> INSERT INTO T VALUES (2, 'THIS RECORD ONE, CAN BE QUERY IN NORNAL');

1 row created.

SQL> INSERT INTO T VALUES (3, 'THIS RECORD CAN BE QUERY IN SENTERNCE.');

1 row created.

SQL> INSERT INTO T VALUES (4, 'THIS RECORD
2 ARE TESTED FOR
3 THE QUERY IN PARAGRAPH');

1 row created.

SQL> COMMIT;

Commit complete.


SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP CTXSYS.NULL_SECTION_GROUP');

Index created.

建 立一个NULL_SECTION_GROUP 属性的索引很简单,而且NULL_SECTION_GROUP不启用节搜索,因此查询上也没有什么特殊的东西。但是NULL_SECTION_GROUP 可以支持Oracle预定义的两种节搜索,SENTENCE和PARAGRAPH,下面就简单说明一下这两个特性:

SQL> column docs format a50

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'RECORD AND QUERY') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN SENTENCE') > 0;
SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN SENTENCE') > 0
*
ERROR at line 1:
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-10837: section SENTENCE does not exist


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN PARAGRAPH') > 0;
SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN PARAGRAPH') > 0
*
ERROR at line 1:
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-10837: section PARAGRAPH does not exist

在默认情况下,没有设置这两个节,因此相应的查询语法会报错:

SQL> DROP INDEX IND_T_DOCS;

Index dropped.


SQL> BEGIN
2 CTX_DDL.CREATE_SECTION_GROUP('TEST_NULL', 'NULL_SECTION_GROUP');
3 CTX_DDL.ADD_SPECIAL_SECTION('TEST_NULL', 'SENTENCE');
4 CTX_DDL.ADD_SPECIAL_SECTION('TEST_NULL', 'PARAGRAPH');
5 END;
6 /

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP TEST_NULL');

Index created.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'RECORD AND QUERY') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN SENTENCE') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN PARAGRAPH') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH

通过在自定义SECTION GROUP TEST_NULL中设置SENTENCE和PARAGRAPH,使得查询中的节搜索语法顺利执行。但是查询的结果却和我预想的有很大的出入。
这是由于SENTENCE和PARAGRAPH是Oracle预定义的节组,节组预定义的规则完全由FILTER参数控制。因此,不同格式的文章甚至是相同格式不同语言的文档的节属性也都不相同。

经过一系列的测试发现,中文WORD文档的SENTENCE和PARAGRAPH节搜索还是比较好理解的,下面通过一个简单的例子进行说明。

首先,重建测试用表:

SQL> DROP TABLE T;

表已丢弃。

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'TEST.DOC');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_FILE', 'PATH', 'F:');
4 CTX_DDL.CREATE_PREFERENCE('TEST_CHINESE_VGRAM_LEXER', 'CHINESE_VGRAM_LEXER');
5 END;
6 /

PL/SQL 过程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.INSO_FILTER
3 LEXER CTXSYS.TEST_CHINESE_VGRAM_LEXER SECTION GROUP CTXSYS.TEST_NULL');

索引已创建。

索引建立好了,在查询之前,首先看一下被索引文档TEST.DOC的内容:

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

这个例子

可以被

行节查询到。

上面的内容和当前的内容,都可以被段节访问到。

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

上面两条分隔线之间的内容就是被索引的文档。Oracle认为中文的WORD文档中前三行记录属于一个SENTENCE,里面的内容可以被SENTENCE节搜索查询到。而上面的三行和最后的一行中的内容只能通过PARAGRAPH节搜索查询到。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '例子 AND 查询') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 查询) WITHIN SENTENCE') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 查询) WITHIN PARAGRAPH') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '例子 AND 访问') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 访问) WITHIN SENTENCE') > 0;

未选定行

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 访问) WITHIN PARAGRAPH') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

 

 

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的BASIC_SECTION_GROUP。
NULL_SECTION_GROUP 其实并不真正支持节搜索,而在支持节搜索的SECTION_GROUP中,BASIC_SECTION_GROUP是最基础的一种属性,它只支持 以<tag>开头以</tag>结尾的结构的文档。这篇文章在介绍BASIC_SECTION_GROUP的同时,简单介绍一下 节搜索。

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

Table created.

SQL> INSERT INTO T VALUES (1, '<HEADING>TITLE</HEADING>
2 <CONTEXT>This is the contents of the example.
3 Use this example to test the basic_section_group.</CONTEXT>');

1 row created.

SQL> INSERT INTO T VALUES (2, '<HEADING>EXAMPLE</HEADING>
2 <CONTEXT>This line incluing the word title too.</CONTEXT>');

1 row created.

SQL> COMMIT;

Commit complete.

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

Index created.

SQL> SELECT ID FROM T WHERE CONTAINS (DOCS, 'HEADING') > 0;

ID
----------
1
2

在HTML、XML等类似结构的文档中,除了用来显示的内容外,还包括了大量用于控制结构的标识,而这些标识可能是不希望被索引的,而这就是SECTION GROUP其中的一个主要功能。

在上面的例子中,默认情况(NULL_SECTION_GROUP)肯定会将HEADING放入到索引键值中,但如果建立了BASIC_SECTION_GROUP则在

查询文档的时候,HEADING、CONTEXT等标签内容将不再被索引

SQL> DROP INDEX IND_T_DOCS;

Index dropped.

SQL> exec CTX_DDL.CREATE_SECTION_GROUP('TEST_BASIC', 'BASIC_SECTION_GROUP');

PL/SQL procedure successfully completed.

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP TEST_BASIC');

Index created.

SQL> SELECT ID FROM T WHERE CONTAINS (DOCS, 'HEADING') > 0;

no rows selected

SQL> SELECT ID FROM T WHERE CONTAINS (DOCS, 'USE') > 0;

ID
----------
1


节搜索的另一个主要功能就是可以限制查询的范围。如果上面的例子中,文档包含了两部分,标题和正文,其中标题使用标签

<HEADING>和<HEADING>,正文使用标签<CONTEXT>和<CONTEXT>。因此,可以对BASIC_SECTION_GROUP添加区域属性,运行查询在文档的某个范围内进行。

SQL> DROP INDEX IND_T_DOCS;

Index dropped.

SQL> exec CTX_DDL.ADD_ZONE_SECTION('TEST_BASIC', 'HEAD', 'HEADING');

PL/SQL procedure successfully completed.

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP TEST_BASIC');

Index created.

SQL> SELECT ID FROM T WHERE CONTAINS (DOCS, 'TITLE') > 0;

ID
----------
1
2

SQL> SELECT ID FROM T WHERE CONTAINS (DOCS, 'TITLE WITHIN HEAD') > 0;

ID
----------
1

 

 

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的HTML_SECTION_GROUP。

虽然BASIC_SECTION_GROUP 已经可以解决很多基本的节搜索问题,但是Oracle还是推荐对于HTML文档使用专门定义的HTML_SECTION_GROUP属性。这是由于 HTML文档具有很多不规范的表示方法,使用HTML_SECTION_GROUP能够更好的识别HTML文档的机构。另 外,BASIC_SECTION_GROUP不支持不匹配的括号、注释表示和属性等。

下面通过一个简单的例子来看一下HTML_SECTION_GROUP和BASIC_SECTION_GROUP的区别。HTML_SECTION_GROUP支持META标签中的NAME/CONTENT属性对的查询,下面看具体的例子。

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'README.HTML');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_FILE', 'PATH', 'F:');
4 CTX_DDL.CREATE_SECTION_GROUP('TEST_BASIC', 'BASIC_SECTION_GROUP');
5 CTX_DDL.ADD_FIELD_SECTION('TEST_BASIC', 'MTAG', 'META@HTML');
6 CTX_DDL.CREATE_SECTION_GROUP('TEST_HTML', 'HTML_SECTION_GROUP');
7 CTX_DDL.ADD_FIELD_SECTION('TEST_HTML', 'MTAG', 'META@HTML');
8 END;
9 /

PL/SQL 过程已成功完成。

下面看一下README.HTML文档的内容:

<HTML>
<HEAD>
<TITLE>Oracle Ultra Search Sample Crawler Agent Readme</TITLE>
<META NAME="HTML" CONTENT="SECTION GROUP">
</HEAD>
<BODY bgcolor="#FFFFFF">
<h1>Oracle Ultra Search Sample Crawler Agent Readme</h1>
<H2>Table of Contents</H2>
<blockquote> <A REL="CHAPTER" HREF="#CHP1">1. Introduction</A>
<A REL="CHAPTER" HREF="#CHP2">2. Sample agent files</A>
<A REL="CHAPTER" HREF="#CHP3">3. Setting up the Sample Crawler Agent</A>
</blockquote>
<H2><A NAME="CHP1"></A>1. Introduction</H2>
<blockquote>
<p>Oracle Ultra Search provides a sample implementation of user defined data source
agent which uses the Ultra Search agent API. The purpose of this sample is to
provide a concrete illustration on the usage of the agent APIs.
<p>Upon invocation this sample agent connects to a specified Oracle database and
retrieve the contents of a table for the crawler to collect and index.
<p>The sample agent are fully functional and can be customized to adapt to other
database based data source. This agent performs the following task:</p>
<ul>
<li>Reading of data source parameters </li>
<li>Connection to the database that contains the data source </li>
<li>Initialization of fetching document URL and attributes from the data source </li>
<li>Fetching of document URL and attributes from the data source </li>
<li>Disconnection from the data source </li>
</ul>
<p>Complete and comprehensive documentation on agent API is provided in the following
document:</p>
<ul>
<li>Ultra Search Crawler agent API </li>
</ul>
</blockquote>
</BODY>
</HTML>

观察上面的META标签,里面包含NAME/CONTENT属性对,可以根据例子的方式,基于META中名称的值建立FIELD,来搜索CONTENT的值。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.NULL_FILTER
3 SECTION GROUP CTXSYS.TEST_BASIC');

索引已创建。

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

ID DOCS
---------- ----------------------------------------
1 README.HTML

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'SECTION WITHIN MTAG') > 0;

未选定行

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.NULL_FILTER
3 SECTION GROUP CTXSYS.TEST_HTML');

索引已创建。

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

ID DOCS
---------- ----------------------------------------
1 README.HTML

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'SECTION WITHIN MTAG') > 0;

ID DOCS
---------- ----------------------------------------
1 README.HTML

从这个例子可以看出,对于HTML文档来说,使用HTML_SECTION_GROUP可以拥有更多的功能。

最后提醒一下,无论是FIELD_SECTION还是ZONE_SECTION,表示文档的TAG标签都是大小写敏感的,其大小写需要和原文中匹配。

 


这篇文章介绍Oracle全文索引的SECTION GROUP属性中的XML_SECTION_GROUP。

Oracle对HTML文档预定义了专门的HTML_SECTION_GROUP,而对XML文档,也预定义好了专门的SECTION_GROUP——XML_SECTION_GROUP。

其实,Oracle除了XML_SECTION_GROUP外,AUTO_SECTION_GROUP和PATH_SECTION_GROUP也都是为XML文档预定义的,不过,这篇文档先只讨论XML_SECTION_GROUP。

XML文档的格式要求比HTML文档严谨、规范,这也使得XML_SECTION_GROUP比HTML_SECTION_GROUP增加了新的功能,比如ATTRIBUTE的搜索。

如果一篇结构类型下面例子中的文档,使用HTML_SCTION_GROUP和BASIC_SECTION_GROUP都是无法索引到内容的,只能通过XML_SECTION_GROUP的ATTR_SECTION来检索标签属性中的内容。

文档内容如下:

<?xml version="1.0" standalone="yes" ?>
<!-- Copyright (c) 2001 Oracle Corporation. All rights Reserved -->
<!-- Do not modify the contents of this file by hand. -->
<COMP_CONTEXT>
<VAR_LIST SIZE="0">
<VAR NAME="PROD_HOME" TYPE="String" DESC_RES_ID="" SECURE="F" VAL="F:oracleoracle920oracle_java_jdbc_jdbc_common" ADV="F"/>
</VAR_LIST>
<CONST_LIST SIZE="10">
<CONST NAME="Minimal" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Minimal_ALL"/>
<CONST NAME="COMPONENT_DESC" PLAT_SP="F" TYPE="String" TRANS="T" VAL="COMPONENT_DESC_ALL"/>
<CONST NAME="Custom_DESC" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Custom_DESC_ALL"/>
<CONST NAME="Typical_DESC" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Typical_DESC_ALL"/>
<CONST NAME="Complete" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Complete_ALL"/>
<CONST NAME="Custom" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Custom_ALL"/>
<CONST NAME="COMPONENT_NAME" PLAT_SP="F" TYPE="String" TRANS="F" VAL="JDBC Common Files"/>
<CONST NAME="Minimal_DESC" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Minimal_DESC_ALL"/>
<CONST NAME="Typical" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Typical_ALL"/>
<CONST NAME="Complete_DESC" PLAT_SP="F" TYPE="String" TRANS="T" VAL="Complete_DESC_ALL"/>
</CONST_LIST>
</COMP_CONTEXT>

如果建立不同的HTML_SECTION_GROUP或XML_SECTION_GROUP是检索不到内容的:

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'context.xml');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_FILE', 'PATH', 'F:');
4 CTX_DDL.CREATE_SECTION_GROUP('TEST_HTML', 'HTML_SECTION_GROUP');
5 CTX_DDL.CREATE_SECTION_GROUP('TEST_XML', 'XML_SECTION_GROUP');
6 END;
7 /

PL/SQL 过程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.NULL_FILTER
3 SECTION GROUP CTXSYS.TEST_HTML');

索引已创建。

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

未选定行

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.NULL_FILTER
3 SECTION GROUP CTXSYS.TEST_XML');

索引已创建。

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

未选定行

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

对于XML_SECTION_GROUP可以建立ATTRIBUTE节组:

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.ADD_ATTR_SECTION('TEST_HTML', 'NAME', 'CONST@NAME');
3 END;
4 /
BEGIN
*
ERROR 位于第 1 行:
ORA-20000: Oracle Text 错误:
DRG-12225: 这一段类型不能添加到此段组中
ORA-06512: 在"CTXSYS.DRUE", line 157
ORA-06512: 在"CTXSYS.CTX_DDL", line 314
ORA-06512: 在line 2


SQL> BEGIN
2 CTX_DDL.ADD_ATTR_SECTION('TEST_XML', 'NAME', 'CONST@NAME');
3 END;
4 /

PL/SQL 过程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.NULL_FILTER
3 SECTION GROUP CTXSYS.TEST_XML');

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS (DOCS, 'COMPLETE WITHIN NAME') > 0;

ID DOCS
---------- ----------------------------------------
1 context.xml

 

 

 

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的AUTO_SECTION_GROUP。


Oracle的AUTO_SECTION_GROUP是XML_SECTION_GROUP的增强型。对于XML_SECTION_GROUP用户需要自己添加需要定义的节组,而使用AUTO_SECTION_GROUP,则Oracle会自动添加节组以及属性信息。

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

表已创建。

SQL> INSERT INTO T VALUES (1, '<!DOCTYPE TargetMetadata SYSTEM "../dtds/TargetMetadata.dtd">
2
3 <TargetMetadata META_VER="1.0" TYPE="oracle_csa_collector">
4 <Display>
5 <Label NLSID="oracle_csa_collector">CSA Collector</Label>
6 </Display>
7
8 <!-- Metric oracle_csa -->
9 <Metric NAME="oracle_csa" TYPE="EXTERNAL" HELP="NO_HELP">
10 <Display>
11 <Label NLSID="oracle_csa">CSA Configuration</Label>
12 </Display>
13 <QueryDescriptor FETCHLET_ID="OS">
14 <Property NAME="emdRoot" SCOPE="SYSTEMGLOBAL">emdRoot</Property>
15 <Property NAME="scriptsDir" SCOPE="SYSTEMGLOBAL">scriptsDir</Property>
16 <Property NAME="targetGUID" SCOPE="INSTANCE">GUID</Property>
17 <Property NAME="command" SCOPE="GLOBAL"><![CDATA[
18 "%perlBin%/perl" "%scriptsDir%/osm/ecmCollectCSA.pl" -emdroot "%emdRoot%" -outfile "%loaderFile%" -targetguid "%targetGUID%" -indir "%recvFileDir%" -emdURL "%emdURL%"
19 ]]>
20 </Property>
21 </QueryDescriptor>
22 </Metric>
23
24 <InstanceProperties>
25 <InstanceProperty NAME="recvFileDir" CREDENTIAL="FALSE" OPTIONAL="FALSE">
26 <Display>
27 <Label NLSID="ora_recvFileDir_iprop">Receive File Directory</Label>
28 <ShortName NLSID="ora_recvFileDir_iprop">Receive File Directory</ShortName>
29 </Display>
30 </InstanceProperty>
31 </InstanceProperties>
32
33 </TargetMetadata>
34 ');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_SECTION_GROUP('TEST_XML', 'XML_SECTION_GROUP');
3 CTX_DDL.CREATE_SECTION_GROUP('TEST_AUTO', 'AUTO_SECTION_GROUP');
4 END;
5 /

PL/SQL 过程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP CTXSYS.TEST_XML');

索引已创建。

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'CONFIGURATION') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'FILE WITHIN ShortName') > 0;
SELECT ID FROM T WHERE CONTAINS(DOCS, 'FILE WITHIN ShortName') > 0
*
ERROR 位于第 1 行:
ORA-29902: 执行 ODCIIndexStart() 例行程序中出错
ORA-20000: Oracle Text error:
DRG-10837: 段 ShortName 不存在


SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'INSTANCE WITHIN Property@SCOPE') > 0;
SELECT ID FROM T WHERE CONTAINS(DOCS, 'INSTANCE WITHIN Property@SCOPE') > 0
*
ERROR 位于第 1 行:
ORA-29902: 执行 ODCIIndexStart() 例行程序中出错
ORA-20000: Oracle Text error:
DRG-10837: 段 Property@SCOPE 不存在


SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP CTXSYS.TEST_AUTO');

索引已创建。

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'CONFIGURATION') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'FILE WITHIN ShortName') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'INSTANCE WITHIN Property@SCOPE') > 0;

ID
----------
1

通过上面的例子可以看到二者的区别,如果使用XML_SECTION_GROUP, 则用户在进行节搜索的时候,需要使用ADD_ZONE_SECTION、ADD_FIELD_SECTION或ADD_ATTR_SECTION来自己添 加感兴趣的节组,而使用AUTO_SECTION_GROUP,则Oracle会预定义好所有的节组和属性。

使用AUTO_SECTION_GROUP则不能在调用上面三种添加节组的过程,但是可以使用ADD_STOP_SECTION过程,来控制那些部分不能被节搜索访问到。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.ADD_STOP_SECTION('TEST_AUTO', 'ShortName');
3 END;
4 /

PL/SQL 过程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> ALTER INDEX IND_T_DOCS REBUILD PARAMETERS ('REPLACE SECTION GROUP CTXSYS.TEST_AUTO');

索引已更改。

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'FILE') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'FILE WITHIN Label') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'FILE WITHIN ShortName') > 0;

未选定行

指定了STOP_SECTION,仅仅意味着在指定的节组中搜索不到,而在整个文档中,该节组中的内容仍然可见。

另外,需要注意,节组的标识是大小写敏感的。

如果一篇文档大部分的内容都有使用节搜索,那么使用AUTO_SECTION_GROUP属性会相当的方便,但如果一篇文档如果仅仅个别的部分需要使用节搜索,可以考虑使用XML_SECTION_GROUP,并人为的添加个别的SECTION GROUP,这样可以提高索引的创建效率。

 

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的PATH_SECTION_GROUP。

PATH_SECTION_GROUP 的功能和AUTO_SECTION_GROUP十分类似,PATH_SECTION_GROUP比AUTO_SECTION_GROUP增加了 HASPATH和INPATH操作,但是PATH_SECTION_GROUP不支持ADD_STOP_SECTION属性。

下面通过一个例子简单描述一下PATH_SECTION_GROUP以及HASPATH和INPATH功能。

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

表已创建。

SQL> INSERT INTO T VALUES (1, '<!DOCTYPE TargetMetadata SYSTEM "../dtds/TargetMetadata.dtd">
2
3 <TargetMetadata META_VER="1.0" TYPE="oracle_csa_collector">
4 <Display>
5 <Label NLSID="oracle_csa_collector">CSA Collector</Label>
6 </Display>
7
8 <InstanceProperties>
9 <InstanceProperty NAME="recvFileDir" CREDENTIAL="FALSE" OPTIONAL="FALSE">
10 <Display>
11 <Label NLSID="ora_recvFileDir_iprop">Receive File Directory</Label>
12 <ShortName NLSID="ora_recvFileDir_iprop">Receive File Directory</ShortName>
13 </Display>
14 </InstanceProperty>
15 </InstanceProperties>
16
17 </TargetMetadata>
18 ');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP CTXSYS.PATH_SECTION_GROUP');

索引已创建。

AUTO_SECTION_GROUP支持的自动节组属性,PATH_SECTION_GROUP同样支持:

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'COLLECTOR') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'COLLECTOR WITHIN Display') > 0;

ID
----------
1

PATH_SECTION_GROUP还支持HASPATH和INPATH操作:

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'HASPATH(Display)') > 0;

未选定行

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'HASPATH(TargetMetadata/Display)') > 0;

ID
----------
1

SQL> SELECT ID FROM T
2 WHERE CONTAINS(DOCS, 'HASPATH(TargetMetadata/Display/Label="CSA COLLECTOR")') > 0;

ID
----------
1

HASPATH 操作用来判断指定的路径在文档中是否存在。上面的三个查询中,第一个没有查询到内容是因为Display节组不是文档中最顶层的节组。第二个查询到内容是 由于TargetMetadata是最顶层的节组,且TargetMetadata/Display路径存在。第三个查询展示了对于指定路径下的指定内容 是否存在的查询。

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'COLLECTOR INPATH(TargetMetadata)') > 0;

ID
----------
1

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'COLLECTOR INPATH(Display)') > 0;

未选定行

SQL> SELECT ID FROM T WHERE CONTAINS(DOCS, 'COLLECTOR INPATH(//Display)') > 0;

ID
----------
1

INPATH操作和WITHIN操作比较类似,都是在指定的节组中进行查询。

由于Display不是顶层的节组,因此上面的第二个查询没有返回结果,而需要采用第三个查询。

SQL> SELECT ID FROM T
2 WHERE CONTAINS(DOCS, 'RECVFILEDIR INPATH(//InstanceProperty/@NAME)') > 0;

ID
----------
1

SQL> SELECT ID FROM T
2 WHERE CONTAINS(DOCS, 'RECEIVE INPATH(//Display[ShortName="Receive File Directory"])') > 0;

ID
----------
1

SQL> SELECT ID FROM T
2 WHERE CONTAINS(DOCS, 'RECEIVE INPATH(//InstanceProperties[.//ShortName="Receive File Directory"])') > 0;

ID
----------
1

最后列出了几个使用INPATH操作的复杂的查询,这里就不再一一解释了。通过上面的几个例子可以看出,使用INPATH操作比使用WITHIN更加的灵活。

 


Python爬虫实战:实时监控美国SEC官网文件更新,助你第一时间掌握市场动态 在资本市场中,信息就是财富。美国证券交易委员会(SEC)官网公开了大量公司披露文件,涵盖财报、招股说明书、内幕交易等重要信息。对投资者、分析师及法律合规人员来说,实时监控这些公开文件具有重要价值。 阅读详情

相关推荐

人形机器人系列——硬件介绍

人形机器人是多领域交叉技术的产物,主要由三大系统组成:感知系统、决策系统和执行系统。感知系统感知系统是人形机器人获取外界信息的途径,主要由各种传感器组成。其中,视觉传感器用于获取图像信息,如摄像头、激光雷达等;触觉传感器用于感知触碰和压力,如力/力矩传感器、声学传感器等。这些传感器收集到的信息为机器人的决策和执行提供基础。决策系统决策系统是人形机器人的大脑,负责处理和决策各种信息。它由芯片和算法组成。芯片是硬件基础,提供计算能力;算法是软件基础,用于处理和分析传感器收集到的信息,并做出相应的决策。执行系统。

liangwqi的博客 1万+

oracle11g:rman:section size

在Oracle Database 11g之前,RMAN通过并行分配多个通道进行并行备份,每个通道成为一个RMAN会话,但是每个通道一次最多只能备份一个数据文件,这意味着即使有多个通道,每个数据文件也只能通过一个通道进行备份。在Oracle Database 11g的RMAN中,分配的通道可以把一个数据文件分成块,也叫做片段(Section)。您可以指定每个段的大小: RMAN&gt; run ...

viviliving的专栏 1667

cmu15445 2023fall project4 详细过程(包括Bonus Tasks) Concurrency Control

CMU15-445 23fall project 4详解

LA的博客 1604

ORA29902执行ODCIIndexStart()例行程序中出错 SQL空间查询ST_Geometry配置

在PLSQL中执行ST空间查询出现错误: 区域条件查询SQL空间查询语句: Select count(tln.objectid) as cid From 表空间名.表名 tln where sde.st_intersects(tln.shape,sde.st_buffer(sde.st_geometry('polygon ((49971.1664251336 42122.0686524059, 4...

weixin_34416754的博客 2027

Kindle电子书DRM破解全攻略:从下载到转换的完整流程(含最新DeDRM插件配置)

本文详细介绍了如何合法移除个人购买的Kindle电子书的DRM保护,实现跨设备阅读与备份。核心内容包括使用最新DeDRM插件(如noDRM分支)配合Calibre进行配置,并针对亚马逊最新的KFX加密格式提供了密钥提取与实战操作指南。文章强调该方法仅适用于个人合理使用,旨在帮助读者真正掌控自己的数字资产。

delta的博客 576

手把手教你学Simulink--人形机器人控制场景实例:基于Simulink的多连杆人形机器人拉格朗日动力学建模仿真

matlab编辑% 连杆长度 (m)% 躯干(髋到CoM)% 大腿% 小腿% 质量 (kg)% 转动惯量(绕质心,简化为杆)matlab编辑% 躯干CoM(假设在髋上方L_body/2处)% 左大腿CoM% 左小腿CoM% (右腿类似,略)本文完成了基于Simulink的多连杆人形机器人拉格朗日动力学建模仿真,实现了:✅ 定义7-DOF平面人形结构✅ 使用Symbolic Math Toolbox自动推导动力学方程✅ 生成。

MHD0815的博客 145

ORA-29902: error in executing ODCIIndexStart() routine when creating spatial index with st_geometry

描述 Oracle中的模式(大约24个字符或更大)尝试使用st_geometry创建空间索引可能导致以下Oracle错误: 代码: ORA-29902: error in executing ODCIIndexStart() routine ORA-06502: PL/SQL: numeric or value error: character string buffer too smal...

逝鸿的博客 3024

【5】GD32H7xx CAN发送及FIFO接收

GD32H7xx CAN收发调试记录,包含源码

madao1234的博客 1813

Oracle文本查询

-----------------------------------------------------------------------------------文本查询分类查询文本不同于查询数据,因为有同义词、近义词和反义词。你可能希望搜索互相接近的词或搜索相关联的词。如果仅使用标准的关系操作符,要进行这些查询是非常困难的。通过SQL进行扩充,使其包含文本索引,则ORACLE TEXT允许用户就文本提出非常复杂的问题。文本索引主要有两种CONTEXT和CTXCAT用如下方式建立索引CREATE IND

ocean1010的专栏 3192

芒果YOLO11改进23:主干Backbone篇GhostNet:原创改进高效 GhostNet 网络,华为出品,打造全新检测器

主干Backbone篇GhostNet:原创改进高效 GhostNet 网络,华为出品,打造全新检测器

包括YOLOv5、YOLOv7、YOLOv8等模型改进 404

RV1126 ROS2环境交叉编译及部署(基于官方Docker)

我的所有基于`RV1126`的机器人项目都是在`Ubuntu22.04`下进行开发的,在`Ubuntu18.04 Docker`容器中实现`RV1126`的`SDK`编译,详细可参考我之前的博客[《Ubuntu20.04/22.04下Docker方案实现多平台SDK编译》第2章](https://blog.youkuaiyun.com/w1820020635/article/details/147342689),`RV1126`的`ROS1`部署没什么难度,可以参考我之前的博客,这里记录了`ROS2`交叉编译及问题解决

w1820020635的博客 1142

数据库Oracle Review SectionⅠ Oracle基本配置

Oracle数据库基础 对象关系型的数据库管理系统 (ORDBMS)  在管理信息系统、企业数据处理、因特网及电子商务等领域使用非常广泛 在数据安全性与数据完整性控制方面性能优越  跨操作系统、跨硬件平台的数据互操作能力 Oracle 数据库物理结构和逻辑结构 Oracle 库由操作系统文件组成,这些文件为数据库信息提供实际物理存储 Oracle 库包括逻辑结构和物理结构 物理结...

相信的心就是你的魔法! 306

ABAP Cloud 开发教程的文章目录

本教程涵盖 ABAP 云端 Client 处理、多租户架构、ABAP Cloud开发、动态编程优化、SQL语法改进等技术主题。最新版本1.0.0(更新至2025-12-12),包含197篇文章,重点文章包括《ABAP Client Handling与隔离机制》《ABAP Platform 2021泛型编程》《SAP BTP ABAP多租户应用开发》等,为开发者提供从基础到进阶的实战指南。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1802

oracle xml 索引,oracle全文索引之SECTION GROUP_4_XML_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的XML_SECTION_GROUP。[@more@]Oracle对HTML文档预定义了专门的HTML_SECTION_GROUP,而对XML文档,也预定义好了专门的SECTION_GROUP——XML_SECTION_GROUP。其实,Oracle除了XML_SECTION_GROUP外,AUTO_SECTION_GROUP和PA...

weixin_30234101的博客 202

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

oracle全文索引之SECTION GROUP_3_HTML_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的HTML_SECTION_GROUP。[@more@] 虽然BASIC_SECTION_GROUP 已经可以解决很多基本的节搜索问题,但是Oracle还是推荐...

ckomuo086028的博客 143

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

oracle全文索引之SECTION GROUP_5_AUTO_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的AUTO_SECTION_GROUP。 [@more@]Oracle的AUTO_SECTION_GROUP是XML_SECTION_GROUP的增...

ckomuo086028的博客 116

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

oracle全文索引之SECTION GROUP_4_XML_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的XML_SECTION_GROUP。[@more@] Oracle对HTML文档预定义了专门的HTML_SECTION_GROUP,而对XML文档,也预定...

ckomuo086028的博客 107

oracle全文索引之SECTION GROUP_6_PATH_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的PATH_SECTION_GROUP。[@more@] PATH_SECTION_GROUP 的功能和AUTO_SECTION_GROUP十分类似,PATH...

ckomuo086028的博客 157

oracle全文索引之SECTION GROUP_1_NULL_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的NULL_SECTION_GROUP。[@more@]Oracle的全文索引的SECTION GROUP属性用来支持包含内部结构的文档,比如HTML、XML文档...

ckomuo086028的博客 178

oracle全文索引之SECTION GROUP_2_BASIC_SECTION_GROUP

这篇文章介绍Oracle全文索引的SECTION GROUP属性中的BASIC_SECTION_GROUP。[@more@]NULL_SECTION_GROUP 其实并不真正支持节搜索,而在支持节搜索的SECTION_GROUP...

ckomuo086028的博客 116

全文索引方面

09年马上要结束了,BLOG每天更新又坚持了一年,目前文章总数1700多篇,其中纯技术文章将近1300篇。 我比较喜欢的一句话:十年磨一剑。以前提到过,坚持10年可能会比较困难,那么至少要坚持5年,到目前为止,BLOG更新已经...

ckawt40802的专栏 99

Json Json index 介绍

InsertsDeletesUpdatesQuery TimeNotesInsertsDeletesUpdatesQuery TimeNotesvaluesCommit1 ORACLEbeginend;1 ORACLE1 ORACLE。

jnrjian的博客 375

Oracle 全文索引

缘由 我们经常需要对表的内容进行模糊查询,在数据量不算很大的情况下,使用起来还是没什么问题,因为不会出现明显的慢查询问题。但是当某些时候,单表数据量很大的时候,查询速度就会有明显的变慢问题。此时,我们优先应该考虑的方式是选用特长与全文搜索的技术栈,比如ElasticSearch服务。 BUT,有些时候事与愿违,因为一些列因素导致你只能在数据库的现状情况下优化这样的问题。Oracle的全文索引(Oracle9i 开始支持)可能会对你有帮助。 Oracle全文索引的基本知识 一、历史背景 Oracle数据库的

小单的博客专栏 4602

oracle全文索引之STOPLIST_ CTXCAT 索引_INDEX SET

这篇文章介绍的是ORACLE CTXCAT索引的INDEX SET,也是CTXCAT索引特有的属性。CTXCAT索引是CONTEXT索引的简化版,CTXCAT索引支持的PREFERENCE包括:LEXER、STOPLIST、WORDLIST和STORAGE参数。不支持其他的参数如:DATASTORE、FILTER、SECTIONGROUP。虽然支持LEXER但不支持THEME查

乐敏@技术驿站 1223

oracle 11g全文索引,详解Oracle数据库中文全文索引

详解Oracle数据库中文全文索引日期:2010年5月11日 作者:一、历史背景Oracle数据库的全文检索技术以前十分完满,Oracle Text使Oracle9i具有了强悍的文本检索才干和智能化的文本维护才干。Oracle Text是Oracle9i采用的新称号,在Oracle8/8i中它被称作Oracle interMedia Text,在Oracle8以前它的称号是Oracle ConTe...

weixin_33740713的博客 522

详解Oracle数据库中文全文索引

<br />转载于:http://database.51cto.com/art/200904/121051.htm<br /><br />一、历史背景<br />Oracle数据库的全文检索技术已经非常完美,Oracle Text使Oracle9i具备了强大的文本检索能力和智能化的文本管理能力。Oracle Text是Oracle9i采用的新名称,在Oracle8/8i中它被称作Oracle interMedia Text,在Oracle8以前它的名称是Oracle ConText Cartridge。<b

zgmzyr的专栏 1011
上一篇: oracle全文索引之STORAGE PREFERENCE
下一篇: oracle全文索引之STOPLIST
leminsky
博客等级 码龄22年 43粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值