2

検索するテーブルが 2 つあります。写真のキーワード、タイトル、説明を検索します。キーワードは別の表に分割されています。私の高度な検索では、3 つすべてを検索できますが、基本はキーワード テーブルだけです。

基本的なテーブルのセットアップ:

フォトテーブル

  • 写真付き身分証明書
  • 名前
  • 題名
  • 説明

WORD2PHOTO テーブル

  • ワードID
  • 写真付き身分証明書

ビューとストアド プロシージャを試しましたが、良い結果が得られませんでした。ビューから写真を取得しますが、複数の記録があります。アプリ側でフィルタリングなどを行いますが、サブソニックを使用していて、組み込みのページングを使用したいと考えています。それはまったく別の問題です。

まず、複数のキーワードで検索するにはどうすればよいですか? 次に、タイトルと説明の検索にどのように追加しますか?

検索する現在の単語の一時テーブルを返す関数 (f_Split) があります。

DECLARE @Words TABLE (Word varchar(20))

INSERT INTO @Words (Word)
SELECT Keyword FROM dbo.f_Split('cars|auto|red|fast','|')

生成されたテーブルを使用して写真レコードを取得するにはどうすればよいでしょうか? 何日も苦労していませんか?助けてくれてありがとう。

4

5 に答える 5

1

私は数年前に私のウェブサイトでこれをしました。私がしたことは、SQLがアプリケーションにとって得意ではないことをすべて取り除くことでした。記憶から、それは次のようなものでした:

table photos (
    photoid        number unique indexed,
    name           varchar2,
    title          varchar2,
    description    varchar2,
    keywords       varchar2,
    ... etc
);

table photosearch (
    wordid      number indexed,  -- ID of word, more or less
    photoid     number,          -- ref photos.photoid
    context     number,          -- 9=title, 7=name, 5=desc, ..
    ... etc 
)

写真が挿入/更新されたときの基本的なアルゴリズムは次のとおりです。

photoid = INSERT INTO PHOTOS VALUES (...)

foreach field in (name title description keywords) 
    int weight = getweight(field)
    foreach word in ( value(field) ) 
        # Discard useless words, e.g. "and, or, but, yes, ..."
        stem = word-stem-algorithm(word)
        key  = hash-to-number(stem)
        INSERT INTO PHOTOSEARCH VALUES 
            (key, photoid, weight)

その場合、一般的な検索は次のようになります。

keys [] = hash(stem(word)) foreach word in query

SELECT photoid, sum(context) FROM photosearch
 WHERE wordid IN keys[]
 GROUP BY photoid
 ORDER BY 2 DESC

context == unique_weightを使用するトリックにより、「フィールドに単語が含まれる」検索を簡単に実行でき(読者に演習として残しました;)、フィールドの重みを変更することで結果の順序を「調整」できました。

于 2009-02-20T19:57:14.470 に答える
1

Postgres または MySQL の場合は、次の Web サイトで全文検索用の Sphinx をチェックしてください。

http://www.sphinxsearch.com/

さまざまな Web フレームワーク用の優れたアダプター/プラグインがあります。たとえば、ThinkingSphinx は Ruby on Rails で優れています

http://github.com/freelancing-god/thinking-sphinx

Sphinx は、選択したフィールドでの全文検索、デルタ インデックス作成、適切なスケーリングをサポートしています。

于 2009-02-14T19:37:40.457 に答える
1

複数のキーワードをどのように接続するかを決定する必要があります。誰かが検索で「keyword1 keyword2」と入力した場合、同じ写真に関連付けられる両方のキーワードを探しているか (AND 演算)、同じ写真に関連付けられているいずれか (または両方) のキーワードを探しているか (OR手術)。両方を提供するのはどうですか?そして、「このキーワードで、他のキーワードではない」などはどうでしょう...

ディスク領域の消費以外に、WordID 列が何を提供するのかはわかりません。列として「WordID、Word」を含むテーブルがあり、相互参照テーブルに「PhotoID、WordID」列がある場合、1 つの実用的な設計になります。別の賢明なデザインには、「PhotoID、Word」があります。「WordID、PhotoID、Word」を含むテーブルを持つことは特に賢明ではありません。動作しますが、WordID 列は実質的に使用されていません。そのテーブルで繰り返しがないようにするには、PhotoID と Word の組み合わせに一意の制約が必要です。

@Words (一時) テーブルを指定すると、これを実行して AND オプションを取得できます。

SELECT P.PhotoID, P.Name, P.Title, P.Description
    FROM Photo P, Word2Photo W
    WHERE P.PhotoID = W.PhotoID
    GROUP BY P.PhotoID, P.Name, P.Title, P.Description
    HAVING COUNT(*) = (SELECT COUNT(*) FROM @Words L, Word2Photo M
                           WHERE M.Word = L.Word
                             AND M.PhotoID = P.PhotoID
                      )

Word2Photo テーブルのエントリ数が、特定の写真の @Words テーブルのエントリ数と同じであることを確認します。これは相関サブクエリです。効率的ではありませんが、効果的です。便利なことは、ほとんどの場合 OR オプションで構造を繰り返すことができることです。

SELECT P.PhotoID, P.Name, P.Title, P.Description
    FROM Photo P, Word2Photo W
    WHERE P.PhotoID = W.PhotoID
    GROUP BY P.PhotoID, P.Name, P.Title, P.Description
    HAVING 1 <= (SELECT COUNT(*) FROM @Words L, Word2Photo M
                    WHERE M.Word = L.Word
                      AND M.PhotoID = P.PhotoID
                )

これは、単語リスト内の単語の少なくとも 1 つを含む写真を探します。

他にも方法はあると思いますが、対称性は魅力的です。明らかに、より複雑な基準 (AND と OR の混合、または NOT の追加) に入ると、構造が変化します。

警告

テストされていないコード。

于 2009-02-14T20:43:33.637 に答える
0

あなたが何を意味するのかは完全には明らかではありませんが、あなたが望んでいるように聞こえます:

SELECT /* some columns */
FROM @Words #w
INNER JOIN WORD2PHOTO wp ON wp.Word = #w.Word
INNER JOIN PHOTO p NO p.PhotoID = wp.PhotoID

タイトルと説明について。まあ、あなたは何か不器用なことをすることができますLIKE.タイトル/説明) - これは次のようになります。

SELECT /* some columns */
FROM @Words #w
INNER JOIN WORD2PHOTO wp
   ON wp.Word = #w.Word
   AND wp.Source IN ('K','T','D') -- keywords/title/description
INNER JOIN PHOTO p NO p.PhotoID = wp.PhotoID

そして、それに合わせて K/T/D のさまざまな組み合わせを含めるだけです...

タイトル/説明を INSERT/UPDATE するときに、既存の T/D エントリがすべて削除され、新しいエントリに置き換えられるようにトリガーが必要です。

于 2009-02-14T19:28:14.113 に答える