8

Modeshape のような JCR によるタグベースの検索システムが必要です。いくつかのタグでノードを検索したい。質問は、それを実装する最良の方法は何ですか?

  1. タグの新しいノード タイプと mixin を追加します。それが正しい場合、ユーザーに表示されるタグ名をどこで定義できますか?
  2. タグの階層を実装し、ノードでそれらを参照します。それが本当なら、どうすればそれらを参照できますか?
  3. その他の方法で。
4

1 に答える 1

13

JCR でタグを実装するには、いくつかの方法があります。どのオプションを選択するかは、独自のアプリケーションのニーズによって異なります。ここに私が知っている4つのオプションがあります。

オプション 1: ミックスインを使用する

タグごとに、マーカー mixin である mixin ノード タイプ定義を定義し (プロパティ定義や子ノード定義はありません)、NodeTypeManager を使用して動的に登録します。次に、ノードに「タグ付け」したい場合は、そのノードにタグを表す mixin を追加するだけです。どのノードも複数のタグを持つことができ、特定のタグを持つすべてのノードを照会できます。

(この応答の残りの部分では、「acme」は一般的な名前空間として使用されています。これを、独自のアプリケーションと組織に適した名前空間に置き換える必要があります。)

たとえば、「acme:tag1」というタグが指定されている場合、次の単純なクエリを使用して、このタグを持つすべてのノードを見つけることができます。

SELECT * FROM [acme:tag1]

このアプローチの欠点は、タグの維持が面倒なことです。新しいタグを作成するには、新しいノード タイプを登録する必要があります。タグの名前を簡単に変更することはできませんが、代わりに新しい名前でタグの mixin を作成する必要があります。古いタグを表す mixin を持つすべてのノードを見つけ、古い mixin を削除し、新しい mixin を追加します。最後に、古いタグのノード タイプ定義を削除します (どこでも使用されなくなった後)。古いタグの削除も同様の方法で行います。もう 1 つの欠点は、追加のメタデータ (表示名など) をタグに関連付けるのが容易ではないことです。これは、追加のプロパティがノード タイプの定義で許可されていないためです。

このアプローチは非常にうまく機能するはずです。

オプション 2: 分類法と強力な参照を使用する

このアプローチでは、各タグ (分類法など) のノードを作成できるリポジトリの領域に単純なノード構造を作成します。このノードでは、タグを説明するプロパティ (表示名など) を設定できます。これらのプロパティはいつでも変更できます (タグの名前を変更する場合など)。

次に、タグをノードに「適用」するには、タグとの何らかの関係を作成する必要があります。1 つの方法は、タイプ REFERENCE の「acme:tags」多値プロパティを含む mixin ノード タイプを定義することです。1 つまたは複数のタグをノードに適用する場合は、ノードに mixin を追加し、「acme:tags」プロパティをタグ ノードに設定するだけです。

特定のタグのすべてのノードを検索するには、タグ ノードで「getReferences()」を呼び出して、タグ ノードへの参照を含むすべてのノードを検索します。

このアプローチには、すべてのタグを 1 つ以上の分類法 (おそらくユーザー固有の分類法を含む) 内で制御/管理する必要があるという利点があります。ただし、いくつかの欠点もあります。何よりもまず、REFERENCE プロパティのパフォーマンスが優れていない可能性があります。一部の JCR 実装では、REFERENCES の使用をまったく推奨していません。ModeShape はそうではありませんが、同じノードへの参照を含むノードが多数ある場合 (たとえば、単一のタグを持つ多数のノード)、ModeShape は REFERENCE のパフォーマンスを低下させ始める可能性があります。

オプション 3: 分類法と弱参照を使用する

このオプションは、「acme:tags」プロパティが REFERENCE ではなく WEAKREFERENCE になることを除いて、上記のオプション 2 と同様のハイブリッドです。1 つ以上の分類法を定義して管理することもできます。特定のタグを持つノードを見つけるために、タグ ノードで "getReferences()" メソッドを使用することはできませんが (WEAKREFERENCE プロパティでは機能しないため)、クエリを使用して簡単にこれを行うことができます。

SELECT * FROM [acme:taggable] AS taggable 
JOIN [acme:tag] AS tag ON taggable.[acme:tags] = tag.[jcr:uuid]
AND LOCALNAME(tag) = 'tag1'

このアプローチでは、1 つ以上のタクソノミーの使用が強制され、タグを使用する前にタクソノミーに存在する必要があるため、タグの制御が少し簡単になります。名前の変更と削除も簡単です。WEAKREFERENCE プロパティは、すべてが 1 つのノードを指しているか多数のノードを指しているかに関係なく、多数の参照でパフォーマンスが向上するため、パフォーマンスに関しては、REFERENCE アプローチよりも優れています。

欠点は、タグがまだ使用されていても削除できることですが、削除されたタグへの WEAKREFERENCE を含むノードは無効になります。これは、アプリケーション内のいくつかの慣習によって、または単純にタクソノミーのメタデータを使用して、特定のタグが「非推奨」であり、使用されるべきではないことを示すことによって修正できます。(IMO、後者は実際にはこのアプローチの利点です。)

このオプションは、通常、オプション 2 よりもはるかに優れたパフォーマンスとスケーリングを実現します。

オプション 4: 文字列プロパティを使用する

さらに別の方法として、単純に STRING プロパティを使用して、適用するタグの名前で各ノードにタグを付ける方法があります。たとえば、複数の値を持つ STRING プロパティを定義する mixin (例: "acme:taggable") を定義し、ノードにタグを付けたい場合は、単に mixin を追加し (まだ存在しない場合)、その名前を追加します。 「acme:tags」STRING プロパティの値としてタグを付けます (まだ値として存在していない場合は繰り返します)。

このアプローチの主な利点は、非常に単純であることです。タグ付けするノードで文字列値を使用するだけです。特定のタグ (「tag1」など) でタグ付けされたすべてのノードを検索するには、単純にクエリを発行します。

SELECT * 
FROM [acme:taggable] AS taggable 
WHERE taggable.[acme:tags] = 'tag1'

タグの管理は簡単です。管理はありません。タグの名前を変更する場合は、タグの値の名前を変更できます。タグを削除する (およびタグ付けされたノードから削除する) 場合は、"acme:tags" プロパティから値を削除することで実行できます (おそらくバックグラウンド ジョブで)。

これにより、任意のタグ名を使用できるため、タグ名がまったく制御されていない場合に最適です。タグ値として使用される文字列のリストを制御する場合は、(上記のオプション 2 と 3 で説明したように) リポジトリに分類法を作成し、アプリケーションで値を分類法の値に制限します。複数の分類法を使用することもできますが、そのうちのいくつかはおそらくユーザー固有のものです。ただし、このアプローチには、オプション 2 または 3 とまったく同じコントロールはありません。

このオプションは、オプション 3 よりも少しパフォーマンスが向上しますが (クエリが単純であるため)、同様にスケーリングされます。

于 2013-01-14T21:32:22.163 に答える