次のコードが私のデータの小さなセットで機能することがわかりましたが、複数のコメントを含むサンプルを取得していないことに気づきませんでした。エントリごとに複数のコメントがある実際のデータベースにコードを適用しようとすると、上記のエラーが発生しました。
現在のコード:
for $doc in doc('test')
let $results :=
(
let $pKeywords := ('best clients', 'Very', '20')
return
for $kw in $pKeywords
return
(
$doc/set/entry[contains(comment, concat('!', $kw))],
$doc/set/entry[contains(comment, $kw)]
)
[not(position() gt 2)]
)
for $i in (1 to count($results))
return
(
subsequence($results/comment, $i, 1),
subsequence($results/buyer, $i, 1)
)
書類:
<set>
<entry>
<comment>The client is only 20 years old. Do not be surprised by his youth.</comment>
<buyer></buyer>
<id>1282</id>
<industry>International Trade; Fish and Game</industry>
</entry>
<entry>
<comment>!On leave in October.</comment>
<comment>!Planning to make a large purchase before Christmas.</comment>
<buyer></buyer>
<id>709</id>
<industry>Real Estate</industry>
</entry>
<entry>
<comment>Is often !out between 1 and 3 p.m.</comment>
<buyer></buyer>
<id>127</id>
<industry>Virus Software Marketting</industry>
</entry>
<entry>
<comment>Very personable. One of our best clients.</comment>
<buyer></buyer>
<id>14851</id>
<industry>Administrative support.</industry>
</entry>
<entry>
<comment>!Very difficult to reach, but one of our top buyers.</comment>
<comment>His wife often answers the phone. That means he is out of the office.</comment>
<buyer></buyer>
<id>1458</id>
<industry>Construction</industry>
</entry>
<entry>
<comment></comment>
<buyer></buyer>
<id>276470</id>
<industry>Bulk Furniture Sales</industry>
</entry>
<entry>
<comment>A bit of an eccentric. One of our best clients.</comment>
<buyer></buyer>
<id>1506</id>
<industry>Sports Analysis</industry>
</entry>
<entry>
<comment>Very gullible, so please !be sure she needs what you sell her. She's one of our best clients.</comment>
<buyer></buyer>
<id>1523</id>
<industry>International Trade</industry>
</entry>
<entry>
<comment>He wants to buy everything, but !he has a tight budget.</comment>
<comment>!His company may be closing soon.</comment>
<buyer></buyer>
<id>1524</id>
<industry>Public Relations</industry>
</entry>
</set>
結果:
Stopped at line 9, column 22: [XPTY0004] document-node()(...): function(item()*) as item()* expected, document-node() found.
同様のエラーが発生して修正できましたが、修正を適用しようとするとうまくいきませんでした。例:
$doc('test')/set/entry[contains(., concat('!', $kw))],
$doc('test')/set/entry[contains(., $kw)]
同じ結果を返します。
目的の結果をたどる:
エントリの子に の 3 つのキーワードのいずれかが含まれている場合、最初のエントリはすべてとその子return
を返す必要があります。entry
comment
$pKeywords
concat('!', $kw)
! を含むコメントを優先することになっています。
2 番目は、最初の の結果からおよびノードをreturn
スライスします。comment
buyer
return
comment
すべてのエントリに という名前のノードが1 つだけ存在する限り、コードは正常に実行されます。という名前のノードが 2 つ以上あるcomment
場合、コードは失敗し、コンパイラは上記のエラーを返します。
Stopped at line 9, column 22: [XPTY0004] document-node()(...): function(item()*) as item()* expected, document-node() found.
-編集-
望ましい結果:
<comment>The client is only 20 years old. Do not be surprised by his youth.</comment>
<buyer/>
<comment>Very personable. One of our best clients.</comment>
<buyer/>
<comment>!Very difficult to reach, but one of our top buyers.</comment>
<buyer/>
<comment>A bit of an eccentric. One of our best clients.</comment>
<buyer/>
望ましい結果を明確にする:
//contains ! and the first keyword, "best clients"; so, the first result should come from this entry.
<entry>
<comment>Very gullible, so please !be sure she needs what you sell her. She's one of our best clients.</comment>
<buyer></buyer>
<id>1523</id>
<industry>International Trade</industry>
</entry>
//Only one entry contains ! and "best clients". So, the first result containing "best clients" contains nodes for the second result.
<entry>
<comment>Very personable. One of our best clients.</comment>
<buyer></buyer>
<id>14851</id>
<industry>Administrative support.</industry>
</entry>
//This contains ! and the second keyword, "Very", but it is a duplicate. So, ideally its children should not be returned.
<entry>
<comment>!Very difficult to reach, but one of our top buyers.</comment>
<comment>His wife often answers the phone. That means he is out of the office.</comment>
<buyer></buyer>
<id>1458</id>
<industry>Construction</industry>
</entry>
//This contains ! and a string, "very" (part of everything). Nodes from this entry should be returned as the third result.
<entry>
<comment>He wants to buy everything, but !he has a tight budget.</comment>
<comment>!His company may be closing soon.</comment>
<buyer></buyer>
<id>1524</id>
<industry>Public Relations</industry>
</entry>
//The only entry whose comment child contains the keyword '20'. There is no '!'-containing comment with 20, so this nodes is the top and only node whose children should be returned.
<entry>
<comment>The client is only 20 years old. Do not be surprised by his youth.</comment>
<buyer></buyer>
<id>1282</id>
<industry>International Trade; Fish and Game</industry>
</entry>
-編集2-
次のパスでは、何を達成しようとしているのかをよりよく理解できますが、明らかな構文エラーがいくつかあります (たとえば、8 行目に見られるように、配列の操作方法をまだ発見していません)。構文エラーを解決したら、これを更新します。
<set>
{
let $kw := ('best clients', 'Very', '20')
let $entry := doc('test')/set/entry
let $priority := '!'
for $i in (1, count($kw))
let $priority_result[$i] :=
(
for $entries in $entry
where $entry contains(., $priority) and where $entry contains $kw[$i]
return subsequence($priority_result[$i], 1, 2)
)
if $priority_result[$i] < 2
for $i in (1, count($kw))
let $secondary_result[$i] :=
(
for $entries in $entry
where $entry contains $kw[$i] and where $entry not($priority_result) and where $entry not($secondary_result[1..($i-1)])
return $secondary_result[$i]
)
else let $secondary_result[$i] := ''
for $i in (1, count($kw))
return
(
$primary_result[$i],
$secondary_result[$i]
)
}
</set>
そして、null の結果を返す提案された変更:
for $doc in doc('test')
let $results :=
(
let $pKeywords := ('best clients', 'Very', '20')
return
for $kw in $pKeywords
return
(
$doc/set/entry/comment[contains(., concat('!', $kw))],
$doc/set/entry/comment[contains(., $kw)]
)
[not(position() gt 2)]
)
for $i in (1 to count($results))
return
(
subsequence($results/comment, $i, 1),
subsequence($results/buyer, $i, 1)
)