【IT168技术文档】
在DB2 V9中,可以通过DB2 Net Search Extender工具,实现对存储在数据库中的 XML 数据进行全文本搜索。DB2 Net Search Extender 完全支持 XML 数据类型。它使得可以对存储在 XML 列中的文档建立全文本索引。通过对 XML 列创建文本索引,可以查询 XML 文档中的所有文本并执行一些搜索(如相似搜索或通配符搜索)。DB2 Net Search Extender 是DB2 数据服务器产品的一部分,需要单独安装。
下面示例显示了一个简单的全文本搜索,它要在 DEPTDOC 列中存储的 XML 文档的路径⁄dept⁄description 中的任意位置查找单词“marketing”:
SELECT DEPTDOC
FROM DEPT
WHERE contains (DEPTDOC, SECTIONS("⁄dept⁄description") "marketing") = 1
DB2 Net Search Extender 提供的 contains 函数允许在路径 ⁄dept⁄description 中的任何文本(包括元素或属性名以及元素或属性值)中搜索字符串“marketing”。
要使用全文本搜索,必须使用 SQL。但是,仍可以将 SQL 查询的结果返回至 XQuery 上下文以进行进一步处理。下面示例显示使用全文本搜索的 SQL 查询产生的结果如何参与 XQuery 表达式:
XQUERY for $i in db2-fn:sqlquery ('SELECT DEPTDOC FROM DEPT WHERE contains (DEPTDOC, SECTIONS("⁄dept⁄description") "marketing") = 1')//employee return $i/name
在此示例中,使用全文本搜索的 SQL 查询的结果返回至 XQuery FLWOR 表达式的 for 子句。然后,for 子句返回所有 <employee> 元素,并且 return 子句返回检索到的 <employee> 元素中的 <name> 元素。
如何搜索存储的 XML 文档
本文中以数据库名 DEMO和create table t1 (c1 varchar(10) not null primary key,c2 xml)为例
需要如下几个步骤:
1. 启用全文检索服务
db2text enable database for text connect to demo
2. 启动全文检索服务
db2text start
3. 创建全文检索索引
db2text create index i1 for text on t1(c2) connect to demo
4. 更新全文检索索引信息
db2text update index i1 for text connect to demo
5. 搜索信息
下列将详细描述对 XML 文档如何建立索引进行搜索,以及如何将此功能集成到 XQuery 处理中。SELECT c2 FROM t1
WHERE CONTAINS(c2, SECTIONS("/purchaseOrder/item/name") “Rake”) = 1
通常,对 XML 数据列创建索引时,不需要指定格式(FORMAT)。缺省情况下,当对 XML 列创建文本索引时,Net Search Extender 将选择 XML 格式。不允许对 XML 数据列使用格式说明符 TEXT 和 HTML。
在用来说明对 XML 列创建和使用文本索引的后续样本中,使用了以下 XML 文档。该 XML 文档存储在 t1 表的 c2 列(类型为 XML)中。
<?xml version="1.0">
<purchaseOrder orderDate="2001-01-20">
<shipAddress countryCode="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Hill</city>
<zip>90999</zip>
</shipAddress>
<item partNo="123" quantity="1">
<name>S&B Lawnmower Type ABC-x</name>
<price>239.90</price>
<shipDate>2001-01-25</shipdate>
</item>
<item partNo="987" quantity="1">
<name>Multifunction Rake ZYX</name>
<price>69.90</price>
<shipDate>2001-01-24</shipdate>
</item>
</purchaseOrder>
使用缺省文档模型建立索引
如果在 CREATE INDEX 语句中没有指定任何文档模型,那么 Net Search Extender 将使用缺省文档模型。
缺省文档模型的一个特征就是:节名在用于指定每个元素和属性的绝对路径的 XPath 表示法中。注意,搜索查询中的节名并不是在执行查询期间求值的 XPath 表达式。它们是用来表示结构化文档中的特定部分(元素和属性)的一些名称。
如果您未在使用模型文件,那么按如下所示为 XML 文档定义文本索引:
db2text CREATE INDEX i1 FOR TEXT ON t1(c2) CONNECT TO demo
由于 c2 列的数据类型为 XML,因此可以省略 FORMAT 规范。在此情况下,FORMAT 规范缺省设置为 XML。
当未指定文档模型时,对于每个 XML 元素,都将根据它在文档中的绝对 XPath 来自动为它指定一个名称。例如,在搜索查询中,通过节名 /purchaseOrder/item/price 就可以访问 price 元素。使用节名 /purchaseOrder/shipAddress/@countryCode 就可以访问 countryCode 属性。
在使用 db2text update 命令更新索引之后,将 SECTION 搜索与标量搜索函数配合使用的 SQL 表达式可能如下所示:
查询将返回如上所示的样本 XML 文档。SELECT c2 FROM t1
WHERE CONTAINS(c2, SECTIONS("/purchaseOrder/item/name") “Rake”) = 1
使用定制文档模型建立索引
如果想定义定制的节名,那么必须指定一个模型文件来对文档的某些部分指定用户定义的名称。使用文档模型的一个优点是:可以指定您想要对 XML 文档的哪些部分建立索引,并使用 XPath 表达式来指定这些部分。
以上 XML 文档的模型文件可能如下所示:
<?xml version="1.0"?>
<XMLModel>
<XMLFieldDefinition
name="itemName"
locator="/purchaseOrder/item/name" />
<XMLFieldDefinition
name="customerName"
locator="//shipAddress/name" />
<XMLAttributeDefinition
name="partNumber"
type="NUMBER"
locator="/purchaseOrder//item/partNo" />
<XMLFieldDefinition
name="none"
locator="/purchaseOrder/orderDate"
exclude="yes" />
</XMLModel>
注意,文档模型为上面的搜索查询中所引用的 /purchaseOrder/item/name 元素指定名称 itemName。
使用模型文件的索引定义为:
CREATE INDEX i1 FOR TEXT ON t1(c2) DOCUMENTMODEL XMLModel IN
/mydir/myfilename/xmlmodel.xml CONNECT TO demo
(使用 DOCUMENTMODEL 参数指定的)文档模型名指定模型文件中的根元素。这是 XML 文档模型的 XMLModel。路径 /mydir/ ... 指向用于定义模型的文件。
在使用上述模型文件创建文本索引并且使用 db2text update 命令更新索引之后,就可以按如下所示搜索 /purchaseOrder/item/name 元素:
SELECT c2 FROM t1
WHERE CONTAINS(c2, SECTIONS("itemName") “Rake”) = 1
注意与搜索查询的差别,搜索查询未指定文档模型。但是这两种查询都会返回上面所提到的同一样本 XML 文档。
XML 文档模型还会对 item 元素的 XML 属性 partNo 定义一种 partNumber 属性。Net Search Extender 属性定义的数据类型必须始终是 NUMBER。
上述样本模型文件中的属性定义允许对如下所示的值范围进行搜索:
SELECT c2 FROM t1 WHERE CONTAINS
(c2, ATTRIBUTE “partNumber” BETWEEN 300 AND 500) = 1
使用XQuery 处理搜索结果
当在数据库中搜索 XML 文档时,还可以使用 XQuery 来处理搜索结果。通过利用 DB2® 的混合数据库引擎,可以将 SQL 文本搜索查询与 XQuery 处理组合在一起。
这是通过在 XQuery 上下文中使用 db2-fn:sqlquery() 输入函数来完成的。要使用 XQuery 输入函数,必须使用 set language XQuery 命令从 SQL 切换到 XQuery,或者在查询前面添加关键字 XQuery 作为前缀。对于解析器来说这是一个重要的指示符,它与 XQuery 表达式一起工作,并且必须遵循应用于 XQuery 语言的区分大小写规则和语法规则。
db2-fn:sqlquery() 函数采用用来表示全查询的字符串文字。db2-fn:sqlquery() 函数将返回一个 XML 序列,该序列表示由全查询选择的 XML 列值的并置结果。
可以使用以下表达式来对存储的 XML 文档同时进行文本搜索和 XQuery 处理:
XQUERY db2-fn:sqlquery(‘SELECT c2 FROM t1
WHERE CONTAINS(c2,
''SECTIONS ("/purchaseOrder/item/name") “Rake” '')
= 1 ')//shipAddress/name
上述查询将返回包含名为“Rake”的采购订单项的 XML 文档中 shipAddress 元素下的所有 name 元素。必须在 SELECT 语句中显式选择 XML 列(在上述示例中为 c2)。
可以按如下所示通过将 FLWOR 构造嵌入到应用程序中来扩展上述样本:
XQUERY FOR $item in db2-fn:sqlquery(‘SELECT c2 FROM t1
WHERE CONTAINS(c2, '' SECTIONS ("/purchaseOrder/item/name") “Rake” '')
= 1 ')
WHERE $item[@partNo > “800”]
RETURN $item/price
注意,对输入函数 db2-fn:sqlquery() 进行全查询时始终都会返回完整的 XML 文档,该 XML 文档中包含产生的匹配项。
考虑存储在数据库中的以下 XML 文档:
<?xml version="1.0"?>
<dept bldg="101">
<employee id="901">
<name>Sabine</name>
<resume>DB2 programmer</resume>
</employee>
<employee id="902">
<name>Holger</name>
<resume>XML expert</resume>
</employee>
</dept>
用于搜索您所在的部门中其履历包含“XML”词条的职员的语句可能如下所示:
SELECT c2 FROM t1 WHERE CONTAINS(c2, SECTIONS("/dept/employee/resume") “XML”)=1
上述搜索查询将返回完整的 XML 文档。按如下所示将该搜索查询嵌入到 XQuery 中:
XQUERY db2-fn:sqlquery(‘SELECT c2 FROM t1
WHERE CONTAINS(c2,
''SECTIONS ("/dept/employee/resume") “XML” '') =1’) //employee/name
它将返回以下两个结果:
<name>Sabine</name>
<name>Holger</name>
注意,尽管职员 Sabine 的履历中没有词条“XML”,但是她还是出现在上述 XQuery 中的结果序列中。之所以如此,是因为该全查询将返回整个文档,即,它将返回完整的 XML 文档,而该 XML 文档中至少有一个职员的履历中具有词条“XML”。
如果想查询只返回结果 <name>Holger</name>,那么发出以下 XQuery 语句:
XQUERY for $d in db2-fn:sqlquery(‘SELECT c2 FROM t1
WHERE CONTAINS(c2,
''SECTIONS ("/dept/employee/resume") “XML” '') =1’)
return §d/dept/employee/name[contains(parent::employee/resume,"XML")];
通过对 XML 列使用对结构敏感的全文本索引,Net Search Extender 就可以滤出在 /dept/employee/resume 节中具有词条“XML”的所有 XML 文档。根据所返回的 XML 文档子集,并且通过使用 XPath 轴来浏览 XML 文档,return 语句 return §d/dept/employee/name[contains(parent::employee/resume,"XML")] 将只返回满足以下条件的那些 <name> 元素:在它们的名为 <resume> 的同代元素中具有 XML。
DB2 V9.5 FP1补丁1新增功能: DB2文本搜索
刚刚发布的修订包 1 中提供的 DB2® 文本搜索为 DB2 数据库提供了集成、可伸缩的搜索技术,可以使用 DB2 文本搜索来执行关系数据、XQuery 和 SQL/XML 文本搜索以及搜索其他文档格式。使用 DB2 文本搜索在 DB2 数据库中执行搜索比以前更容易。
DB2 文本搜索是 DB2 Net Search Extender 的备用方法,后者为 XML 文档提供新的和扩展的搜索支持。DB2 文本搜索包括下列功能:
• 对所有 DB2 数据服务器的文本搜索索引支持。
• 对多种文本格式的文本搜索和索引支持。这些文本格式包括纯文本、HTML 和 XML。
• SQL、SQL/XML 和 XQuery 中的文本搜索功能。
• 精细的搜索分析,例如,处理一个单词的不同形式(如 go、going 和 gone)的能力。
• 同义词字典支持,这允许搜索以查找一段文本的同义词(例如,文本 pretty 的同义词 beautiful),并对文本及其同义词建立索引。
• 支持 XPath 表达式搜索语法并支持在 XPATH 表达式中使用 ftcontains 函数。DB2 Net Search Extender 不支持 XPath 表达式搜索语法。
• 搜索期间进行高级内存管理。
