DB2 中的 XML 全文搜索
词根化
搜索单词的词根形式将搜索词缩减成它的词根,然后再进行搜索。下面的示例搜索 “patern” 的模糊形式或 “creamy” 的词根形式。 词根化搜索返回在文本内容中有 “creamer”、“creamed” 或 “cream” 等词的文档。
清单 20. 对 “creamy” 进行词根化搜索
SELECT pid FROM product
WHERE CONTAINS(description, 'SECTION ("/product/description")
FUZZY FORM OF 42 "patern" | STEMMED FORM OF "creamy"')=1;
通配符
Net Search Extender 支持两种用于通配符搜索的字符匹配:
匹配任何单一字符(_)
匹配任意数量的任何字符(%)
使用通配符搜索的一个查询示例见 清单 21。
清单 21. 用通配符进行搜索
SELECT pid FROM product
WHERE CONTAINS(description, 'SECTION ("/product/description") "pat_ern" & "cream%" ')=1;
这个查询将匹配在 “description” 元素中包含 “pattern” 和 “creamer” 等词的文档。
总需要考虑的一个问题
您可能会奇怪,为什么到目前为止还没有在 “product” 表的 “comments” 列中进行搜索。这是因为要用它讲解在 XML 文档中进行搜 索的一个重要方面:总是返回完整的 XML 文档作为搜索结果,而不只是出现匹配的特定文档部分或元素。
我们以 “comments” XML 文档为例讲解这个问题,这些文档的基本结构见 图 2。与 “product” 文档相比,这些文档有一个不同的结 构性质。在 “comments” 元素中,有多个重复的 “comment” 元素。
例如,要搜索在评论的 “message” 元素中有 “disappointing” 词根形式的产品的名称,可以编写下面的查询:
清单 22. 搜索在评论的 “message” 元素中有 “disappointing” 词根形式的产品的名称
SELECT XMLQUERY ('$prod//name' passing description as "prod")
FROM product
WHERE CONTAINS(comments, 'SECTION ("/comments/comment/message")
STEMMED FORM OF "disappointing"')=1
这个查询以以下方式返回产品的名称:
<name>Sterling Sugar & Creamer by Gorham</name>
1 record(s) selected.
只要不直接访问重复的部分,比如这个示例中 “comments” 列中的 “comment” 元素,那么搜索具有重复文档部分的 XML 文档 无需任何进一步的考虑就可工作。
但是,如果希望获得发表了包含 “disappointment” 的评论的顾客的 “customerID”,那么第一种寻找这一信息的方法如下:
清单 23. 获得发表了包含 “disappointment” 的评论的顾客的 “customerID”
XQuery for $co in db2-fn:sqlquery ("SELECT comments
FROM product
WHERE CONTAINS(comments,
'SECTION("/comments/comment/message")
STEMMED FORM OF "disappointed"')=1")
return $co//customerID
返回的 XML 元素序列是:
清单 24. 返回的 XML 元素序列
<customerID>1187594</customerID>
<customerID>238461</customerID>
![]()
2 record(s) selected
可以看到,没有发表 包含 “disappointment” 的评论的顾客的 “customerID” 也返回了。
类似,这个查询在 SQL 上下文中可以表示为:
清单 25. SQL 上下文中表示的同一查询
SELECT XMLQUERY('$co//customerID' passing comments as “co”)
FROM product
WHERE CONTAINS(comments, 'SECTION("/comments/comment/message")
STEMMED FORM OF "dissapointed"')=1
返回的序列是:
<customerID>1187594</customerID><customerID>238461</customerID>
1 record(s) selected.
同样,这个搜索查询返回两个 “customerID” 元素,因为搜索总是返回完整的 XML 文档。在处理 XML 搜索结果时,考虑到这个 方面很重要。但是,如何能够获得要寻找的单一 “customerID” 呢?
在不使用词根化那样的高级搜索功能的情况下,解决方案可能是使用前面介绍过的 contains() XQuery 内置函数。
以下查询使用全文搜索信息过滤出在 “message” XML 元素中有 “disappointing” 的那些文档。对这些文档的搜索返回满足搜索条件 的完整 “comments” 文档。与前面的查询相反,以下查询使用 contains() XQuery 函数在 message 元素上添加一个谓词。这样的话,满 足全文搜索条件的这些文档会根据 XPath 谓词进一步进行过滤。
清单 26. 满足全文搜索条件的文档根据 XPath 谓词进一步进行过滤
SELECT XMLQUERY('$co/comments/comment[contains (message,"disappointing")]
/customerID' passing comments as "co")
FROM product
WHERE CONTAINS(comments, 'SECTION("/comments/comment/message")
"disappointing"')=1;
同样的查询也可以在 XQuery 上下文中表示:
清单 27. XQuery 上下文中表示的同一查询
XQuery for $co in db2-fn:sqlquery('SELECT comments FROM product
WHERE CONTAINS(comments,
''SECTION("/comments/comment/message") "disappointing" '')=1')
return $co/comments/comment[contains(message,"disappointing")]/customerID
这两个查询都返回发表了不满意评论的顾客的 “customerID” 元素。
<customerID>238461</customerID>
1 record(s) selected
