数据库中如何实现XML文档的全文本搜索
使用定制文档模型建立索引
如果想定义定制的节名,那么必须指定一个模型文件来对文档的某些部分指定用户定义的名称。使用文档模型的一个优点是:可以指定您想要对 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。
0
相关文章