3

以下是 XML 结构 - (我给出了整个文档的一小部分数据有限。我有一个 6 GB 的 XML DB,具有适当的全文索引。)

<Docs>
 <Doc>
<Chap>No - 1</Chap>
<Desc>
  <Notes>
    <Para t="sn">departmental report</Para>
  </Notes>
  <Notes>
    <Para t="sn">The equiry commission is good.</Para>
  </Notes>
  <Notes>
    <Para t="sn">departmental process</Para>
    <Para t="ln">The enquiry report for the bomb blast is yet to come.<bL/>
      <bL/>The department working on this is quite lazy.</Para>
  </Notes>
</Desc>
</Doc>
<Doc>
<Chap>No - 2</Chap>
<Desc>
  <Notes>
    <Para t="sn">Enquiry Processes Report</Para>
    <Para t="ln">The enquiry process is very simple.<bL/>
      <bL/>With proper guidance anybody can handle the commission easily.<bL/>
      <bL/>
    </Para>
  </Notes>
  <Notes>
    <Para t="sn">Enquiry - Departmental</Para>
  </Notes>
</Desc>
 </Doc>
 <Doc>
<Chap>No - 3</Chap>
<Desc>
  <Notes>
    <Para t="sn">Physics Department</Para>
  </Notes>
  <Notes>
    <Para t="sn">Working process of physics department is quite lengthy</Para>
    <Para t="ln">Even after proper enquiry, I was told nothing.<bL/>
      <bL/>This was like a bomb blast.</Para>
  </Notes>
  <Notes>
    <Para t="sn">Departmental enquiry.</Para>
    <Para t="ln">There should be a departmental enquiry for this wrong process.</Para>
  </Notes>
</Desc>
</Doc>
</Docs>

现在我想要所有那些Chap包含所有单词“部门”、“查询”和“报告”的节点。

到目前为止,我无法使用各种组合来获得它们。我的尝试之一是 -

for $x in ft:search("Docs", ("departmental enquiry report"), map{'mode':='all words'})/ancestor::*:Para
 return $x/ancestor::Chap

任何人都可以指导我吗?

4

2 回答 2

1

BaseX 的全文索引引用了文本节点级别的所有术语。这意味着您的所有单词都需要出现在同一个文本节点中。

如果您想利用全文查询并查找出现在某个元素下方的所有单词,您可以尝试以下查询:

let $words := ("departmental enquiry report")
for $doc in db:open("Docs")//Doc[.//text() contains text { $words } any word]
where $doc[string-join(.//text(), ' ') contains text { $words } all words]
return $doc/Chap

第一个contains text表达式将被重写为索引请求。它将返回返回任何搜索词的所有文本。子句中的 contains 文本表达式where将过滤掉所有不包含所有查询词的节点。使用string-join(.//text(), ' '),将连接 Doc 元素下方的所有文本节点,并在连接的字符串上执行搜索。

以下查询的等效表示应产生相同的结果:

let $words := ("departmental enquiry report")
for $x in ft:search("Docs", $words, map { 'mode': 'any word' })/ancestor::*:Doc
where ft:contains(string-join($x//text(), ' '), $words, map { 'mode': 'all words' })
return $x/Chap
于 2014-02-27T09:29:50.383 回答
1

ft:search,以及为什么它不能解决问题

通过查看BaseX 的 XQuery 全文文档,您会意识到其中的第二个参数ft:search应该是一个单词序列:

ft:search($db as xs:string, $terms as item()*, $options as item()) as text()*

因此,您的查询应该类似于

for $x in ft:search("Docs", ("departmental", "enquiry", "report"), map{'mode':='all words'})/ancestor::*:Para
return $x/ancestor::Chap

然而这仍然不能解决你的问题,因为这个功能

[re] 返回数据库全文索引中$db包含指定$terms.

换句话说:所有这些词都必须出现在单个文本节点中,但它们在您的示例输入中分布在多个(整个<Doc/>节点上)。

使用标准 XQuery 全文

我不得不从您正在搜索的输入和单词中猜测您实际上想要搜索<Doc/>包含所有这三个单词的节点。

for $document in doc("Docs")/Docs/Doc
where $document contains text { 'departmental', 'enquiry', 'report' } all words
return $document/Chap

这将检索所有文档,对其应用全文搜索,最后返回文档的章节节点。

意识到

  • 我删除了命名空间通配符,因为您的示例文档中不包含命名空间,并且
  • 创建一个全文索引(如果你还没有这样做的话),这将大大提高性能。
于 2014-02-27T09:09:23.737 回答