XQuery全文搜索混合内容

时间:2014-02-27 08:20:35

标签: full-text-search xquery basex

以下是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>

现在我想要所有那些包含所有单词“departmental”,“inquiry”和“report”的Chap个节点。

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

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

任何人都可以指导我吗?

2 个答案:

答案 0 :(得分:1)

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

通过查看BaseX' XQuery Full Text Documentation,您会发现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

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

注意

  • 我删除了名称空间通配符,因为示例文档和
  • 中没有包含名称空间
  • 创建一个全文索引(如果你还没有),这将大大提高性能。

答案 1 :(得分: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表达式将被重写为索引请求。它将返回所有返回任何搜索词的文本。 where子句中的contains文本表达式将过滤掉所有不包含所有查询字词的节点。使用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