検索
チューニング
XQuery
MarkLogic
MarkLogicDay 19

【MarkLogic Server】XQueryチューニングメモ~cts検索条件設定の基本方針

はじめに

今回は、MarkLogicを特徴づけるcts検索における条件関数の基本的な記述方針について整理していきましょう。

cts検索とは?

標準的なXQuery/XPath関数として、W3C標準のfn:docなどが存在します。MarkLogicではこれに加えて独自の索引を用いています。この索引を用いる検索が、cts:searchなどctsを識別子とする関数です。cts関数は、cts:searchのような検索関数と、cts:element-value-queryのように検索条件関数(以下、単に条件関数)があります。
これらをうまく使いこなすことがMarkLogicで性能を出すためのカギになります。

条件関数には必ず、「ドキュメントの中身を見ない」ものをand条件で含めること

DB全体を全文検索することは理論的には可能ですが、現実的には検索範囲が広くなりレスポンスが低くなります。そこで以下のようにドキュメントの中身を見ない条件をcts:and-queryで加えることをお奨めします。いずれも、第1引数は複数の値すなわちシーケンスにすることが可能です。その場合、シーケンス値間はor条件となります。

対象項目 条件関数 備考
ドキュメント cts:document-query -
ディレクトリ cts:directory-query 第2引数で、直下(1)か子孫すべて(infinity)かを選択
コレクション cts:collection-query DB設定の「collection lexicon」はデフォルトでfalseになっているのでtrueに設定

☆よくある修正の例

cts:uris("/a/root/", (), cts:element-value-query(xs:QName("flag"), "007"))
↓
cts:uris((), (), 
  cts:and-query((
    cts:directory-query("/a/root/", "infinity"),
    cts:element-value-query(xs:QName("flag"), "007"))
  ))
)

存在確認だけなら、cts:searchをcts:urisに代える。

cts:searchとcts:urisは、同じcts検索条件を設定できますが中身まで返さなければいけないcts:searchよりも、URIだけを返せばよいcts:urisの方が軽くて済みます。
(ただし、繰り返し要素の設定によって、複数データin1ドキュメントとなっている場合はcts:searchで第1引数にパスを引いて使う必要があります。)
単に検索に引っかかるかを確認すればよいときは、cts:urisを使いましょう。出力数が1個で良い場合は出力数を制限するオプションを設定できます。

☆存在確認を確認して変数$existに代入するクエリの変換

let $query := 
  cts:and-query((
    cts:directory-query("/a/root/", "infinity"),
    cts:element-value-query(xs:QName("flag"), "007"))
  ))
・・・・・
let $exist := 
  cts:search(/*, $query)
  ↓
  cts:uris((), ("limit=1"), $query)

要素完全一致条件の優先度

よく「cts:element-value-queryとcts:element-word-queryってどっちを選べばよいの?」と聞かれるので整理しました。

条件関数 使いどころ
cts:element-range-query 完全一致条件として第2引数に「=」を記述。大小比較や不一致条件としても利用可能。element range indexの設定が前提。
cts:element-value-query 完全一致条件
cts:element-word-query 部分一致条件

*部分一致は、DB設定の変更なども行わないと全てを出力することはできないようです。

一般的に完全一致は部分一致より軽くて済みます。基本的にはcts:element-value-queryを使うようにし、element range indexが設定可能ならば、cts:element-rage-query(..., "=", ...)を使うようにしましょう。

おわりに

cts検索はMarkLogicの性能を担保する上で重要です。一見W3C標準ではない独自の関数として苦手意識を持たれる方もいらっしゃるかもしれませんが、要は問い合わせ言語なわけですから使う関数をいくつか覚えてしまえば、それほど苦にはならないと思います。
MarkLogic社ではトレーニングサイト(英文)もあるようなので、興味のある方は覗いてみてください。

\def\textsmall#1{%
  {\rm\scriptsize #1}
}

免責事項

​​​​​$\textsmall{当ユーザ会は本文書及びその内容に関して、いかなる保証もするものではありません。}$
​​​​​$\textsmall{万一、本文書の内容に誤りがあった場合でも当ユーザ会は一切責任を負いかねます。}$
​​​​​$\textsmall{また、本文書に記載されている事項は予告なしに変更または削除されることがありますので、予めご了承ください。}$