0

私たちのデータベースには、ドキュメント間の関係を含む、多くのメタデータを含むドキュメントが含まれています。架空の例:

<document>
  <metadata>
    <document-number>ID 12345 : 2012</document-number>
    <publication-year>2012</publication-year>
    <cross-reference>ID 67890 : 1995</cross-reference>
    <cross-reference>ID 67890 : 1998</cross-reference>
    <cross-reference>ID 67891 : 2000</cross-reference>
    <cross-reference>ID 12345 : 2004</cross-reference>
    <supersedes>ID 12345 : 2004</supersedes>
    ...
  </metadata>
</document>
<document>
  <metadata>
    <document-number>ID 12345 : 2004</document-number>
    <publication-year>2004</publication-year>
    <cross-reference>ID 67890 : 1995</cross-reference>
    <cross-reference>ID 67890 : 1998</cross-reference>
    <cross-reference>ID 67891 : 2000</cross-reference>
    <cross-reference>ID 12345 : 2012</cross-reference>
    <cross-reference>ID 12345 : 2001</cross-reference>
    <superseded-by>ID 12345 : 2012</superseded-by>
    <supersedes>ID 12345 : 2001</supersedes>
    ...
  </metadata>
</document>

ユーザーがこれらのドキュメントを検索できるようにするために、Marklogic 検索 API に基づく 1 ボックス検索を使用しています。検索文法はさまざまな制約と検索オプションを記述しますが、ほとんどの場合 (そしてデフォルトでは)、メタデータ要素のほとんどを含むように定義されたフィールドで検索し、(ある程度) 慎重に選択された重みを使用します (ここで本当に重要なdocument-numberのは、重さ。)

問題は、ビジネスが非常に具体的な結果の順序付けを望んでいることであり、検索 API を使用してそれを実現する方法が思い浮かびません。

問題を引き起こしている要件は、ユーザー検索が文書番号に一致する場合 (たとえば、「12345」を検索する場合)、その文書番号を持つすべての文書が結果セットの一番上にあり、日付の降順に並べられる必要があることです。それらを結果セットの一番上に置くのは簡単です。document-numberの重みが最も高いため、スコアによる並べ替えは正常に機能します。問題は、すべてのdocument-number一致が他のドキュメントよりも高いスコアを持っていても、同じスコアを持っていないため、日付による 2 番目の並べ替えが機能しないことです。したがって、検索語が残りのドキュメントに表示される頻度で並べ替えられます。メタデータの; これはまったく意味がありません。

私たちが本当に必要としているのは、ドキュメント内の他の一致を参照せずに、検索用語に一致する最も重みの高い要素によって検索 API スコア結果を取得する方法です。私はスコアリングアルゴリズムを見てきましたが、それを行うものは見当たりません。私は何かを逃しましたか、それともこれは不可能ですか?score明らかに、注文する必要はありません。ドキュメント内の単一の最適一致のスコアを取得し、それを並べ替えに使用する他の方法があれば、それで問題ありません。

私が考えもしなかった他の解決策はありますか?

2 つの検索 (document-numberメタデータ ツリー全体に対して 1 つと、メタデータ ツリー全体に対して 1 つ) を実行し、結果を結合することを考えましたが、ページネーションとパフォーマンスに大きな問題が生じるようです。そもそも検索APIを使用する目的に反するものはどれですか。

これらの他の一致を結果セットに含めるのは正しいことを付け加えておく必要があるため、 だけを検索することはできませんdocument-number

4

2 に答える 2

3

高度な検索 API でできることの限界に達したと思います。ただし、提案するいくつかのトリックがあります。これらは 100% 堅牢というわけではありませんが、ビジネスには十分かもしれません。その後、アプリケーションを続行できます。冷笑的または否定的に聞こえる場合は申し訳ありませんが、検索結果を細かく管理することは信じていません。

可能な限り簡単: メモリ内の最初のページを再ソートします。その最初のページは、ユーザーに表示するページよりも少し大きくなる可能性があります。まだサイズが限られているため、それほど苦労することなく、かなり複雑なルールを作成できます。それはあなたの「降順」の問題を解決するでしょう。ページ 1 の結果はページ 2 と完全には一致しませんが、それで十分な場合があります。

複雑さの次のステップとして、ドキュメント品質を使用して降順の問題を処理することを検討してください。このアプローチは、特にhttp://markmail.orgで使用されています。各ドキュメントが挿入または更新されるたびに、日付から導き出された数値を使用してドキュメントの品質を設定します。これは、1970 年からの数日、数週間、数か月、または他の固定日付を使用することができます。新しい結果ほど上位に表示される傾向があります。他のブーストが日付ベースのブーストを圧倒する傾向がある場合は、希望するものに近づく可能性があります.

クエリを分析して、潜在的にブースティングする用語を抽出する場合にも、何らかの用途があるかもしれません。必要に応じてxdmp:exists(cts:search(doc(), $query))、スタンドアローン クエリであるかのように、ブースティング用語ごとに の再帰的な実行を開始できます。結果が見つかったらすぐに救済しますtrue()。つまり、そのクエリ用語をとてつもなく高い重みでブーストして、上位に浮上させることを意味します。

ブースティング タームが何であるかがわかったら、クエリ全体を書き直して、他のすべてのタームの重みをはるかに低い値 (場合によっては 0) に設定します。体重増加。ブースティング項がない場合は、他の調整を行うことができます。ちなみに、これはすべて思ったよりも安価です。呼び出しは別として、xdmp:existsメモリ内の式の評価です。

繰り返しますが、これらはすべてスコアを微調整するためのトリックにすぎません。彼らはあなたが探しているランキングを完全に制御することはできません. 私の経験では、スコアを細かく管理しようとする試みは失敗する運命にあります。ビジネス マネージャーが何と言おうと、ユーザーは未加工の TF/IDF を使用した方が満足するはずです。

于 2012-11-08T16:46:30.853 に答える
2

あなたが提案するように、それを行う別の方法は2つの検索を使用することです。document-number (および理想的にはドキュメントの日付) に範囲インデックスを配置し、潜在的なドキュメント番号の値をクエリから抽出し ( search:parse, extract, その後search:resolve、良い戦略です)、ドキュメントの一致のために cts:element-range-query を実行します日付が降順のドキュメント番号の値。N-result ページを埋めるのに十分な結果がない場合は、検索 API から次の Nx の結果を取得します。最初の結果セットで返されたドキュメントを追跡し、それらの URI を 2 番目の結果セットから除外できます。ページネーションを追跡することはそれほど悪くありません。

これは最初のソリューションほどうまく機能しない可能性がありますが、追加の範囲インデックス クエリと短い検索 API クエリを組み合わせた場合の時間差は、ほとんどの場合、無視できる程度です。

于 2012-11-08T17:40:57.090 に答える