問題描述
在 marklogic 中使用 xquery 返回搜索結果 (Returning search results using xquery in marklogic)
我正在嘗試在 MarkLogic 中使用 XQuery 搜索術語。當我運行以下代碼時,我什麼也得不到。有誰知道問題是什麼?我不使用命名空間,但我認為這不是問題。
注意:當我在 MarkLogic 的查詢控制台中運行此查詢時,我收到此消息:
your query returned an empty sequence
代碼:
{
for $article‑title in /article/front/article‑meta/title‑group/article‑title[cts:contains(., xdmp:get‑request‑field("term"))]
let $article‑title := fn:tokenize(fn:string($article‑title/article/front/article‑meta/title‑group/article‑title), " ")[1 to 100]
let $journal‑title := $article‑title/article/front/journal‑meta/journal‑title‑group/journal‑title/text()
let $contrib := $article‑title/article/front/article‑meta/contrib‑group/contrib/text()
let $year:= $article‑title/article/front/article‑meta/pub‑date/text()
let $sec‑title:= $article‑title/article/body/section/sec‑title/text()
return (
<tr>
<td colspan="10"><hr/></td>
</tr>,
<tr>
<td><b>{$article‑title}</b></td>
<td><b>{$journal‑title}</b></td>
<td>{$contrib}</td>
<td>{$year}</td>
<td>{$sec‑title}</td>
</tr>,
<tr>
<td colspan="10" class="article‑title">{$article‑title} ...</td>
</tr>
)
}
XML示例:
<?xml version="1.0" encoding="UTF‑8"?>
<article article‑type="article" xml:lang="en" structure‑type="article" dtd‑ version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema‑instance">
<front>
<journal‑meta>
<journal‑title‑group>
<journal‑title xml:lang="en">Psychology of Addictive Behaviors</journal‑title>
</journal‑title‑group>
<issn pub‑type="print">0893‑164X</issn>
<issn pub‑type="online">1939‑1501</issn>
<publisher>
<publisher‑name>American Psychological Association</publisher‑name>
</publisher>
</journal‑meta>
<article‑meta>
<article‑id pub‑id‑type="apaID">adb_21_4_462</article‑id>
<article‑id pub‑id‑type="doi">10.1037/0893‑164X.21.4.462</article‑id>
<article‑id pub‑id‑type="pi‑uid">2007‑18113‑004</article‑id>
<article‑categories>
<subj‑group subj‑group‑type="toc‑heading">
<subject>Articles</subject>
</subj‑group>
</article‑categories>
<title‑group>
<article‑title>Social Dominance Mediates the Association of Testosterone and Neurobehavioral Disinhibition With Risk for Substance Use Disorder</article‑title>
</title‑group>
<contrib‑group content‑type="journal‑editors">
<contrib contrib‑type="editor" corresp="no" xlink:type="simple">
<string‑name>
<given‑names>Howard J.</given‑names> <surname>Shaffer</surname>
</string‑name>
<role>Editor</role>
</contrib>
</contrib‑group>
<contrib‑group content‑type="primary‑authors">
<contrib contrib‑type="author" corresp="yes" rid="aff1 corr1" xlink:type="simple">
<string‑name>
<given‑names>Ralph E.</given‑names> <surname>Tarter</surname>
</string‑name>
</contrib>
<contrib contrib‑type="author" corresp="no" rid="aff1" xlink:type="simple">
<string‑name>
<given‑names>Levent</given‑names> <surname>Kirisci</surname>
</string‑name>
</contrib>
<contrib contrib‑type="author" corresp="no" rid="aff1" xlink:type="simple">
<string‑name>
<given‑names>Galina P.</given‑names> <surname>Kirillova</surname>
</string‑name>
</contrib>
<contrib contrib‑type="author" corresp="no" rid="aff1" xlink:type="simple">
<string‑name>
<given‑names>Judy</given‑names> <surname>Gavaler</surname>
</string‑name>
</contrib>
<contrib contrib‑type="author" corresp="no" rid="aff2" xlink:type="simple">
<string‑name>
<given‑names>Peter</given‑names> <surname>Giancola</surname>
</string‑name>
</contrib>
</contrib‑group>
</article‑meta>
</front>
</article>
參考解法
方法 1:
First, there are some errors in your XPath. You were selecting an article‑title
element but treating it as an article
element in the following XPath. Next, you reassigned the $article‑title
variable (which is not actually possible in most XQuery processors ‑ MarkLogic is an exception) to a string, and then executed XPath on that as if it were a node. Then for the remaining variable assignments, you were both operating on a string as if it were a node AND treating the variable as an article
, when it would have been an article‑title
.
I updated the query by changing the for
variable assignment to article
and moving the rest of the XPath into a predicate. Then the other variables were updated to query from the $article
variable instead of $article‑title
, which is a string.
for $article in /article[front/article‑meta/title‑group/article‑title/cts:contains(., xdmp:get‑request‑field("term"))]
let $article‑title := fn:tokenize(fn:string($article/front/article‑meta/title‑group/article‑title), " ")[1 to 100]
let $journal‑title := $article/front/journal‑meta/journal‑title‑group/journal‑title/text()
let $contrib := $article/front/article‑meta/contrib‑group/contrib/text()
let $year:= $article/front/article‑meta/pub‑date/text()
let $sec‑title:= $article/body/section/sec‑title/text()
There are a couple other possibilities I would check, if you continue to have problems: 1) Be sure your call to xdmp:get‑request‑field()
is actually returning the value you expect; 2) Database index settings affect the behavior of cts:contains
, so if any of the elements in the path you are selecting are excluded from the index, then cts:contains
will treat it as if it doesn't exist.
方法 2:
I think the meta‑question here is: how do you debug a complex query when running the query returns nothing (an empty sequence)? It's not very useful for us to debug the query for you, it's much more useful that you should know how to debug it yourself.
If you've got a schema for the source, then running it as a schema‑aware query can be very useful, even if you only do this temporarily for debugging purposes. A schema‑aware query processor will check your path expressions against the schema, and tell you if you are trying to select elements or paths that, according to the schema, can never exist.
After that it's a process of logical deduction, and/or experimentation to distill the query to its essence. Because you've only got one "for" clause, and the return clause always produces something, the only way of getting an empty sequence as the result is if the for clause selects nothing. So that reduces it to a problem with the expression
/article/front/article‑meta/title‑group/article‑title
[cts:contains(., xdmp:get‑request‑field("term"))]
At this stage using an IDE like oXygen can really help: put your source document into the editor, open the XPath evaluator, and enter this path. You'll need to modify it, because it uses MarkLogic extension functions. But you can start by eliminating the predicate and seeing if the path selects anything. I attempted that, but unfortunately your XML isn't well‑formed so I gave up. But it's not difficult to do yourself. If the path expression selects nothing, remove trailing steps from the path until you get a result: the last step that your removed is the one that's wrong.
(by user3054453、wst、Michael Kay)